gpt4 book ai didi

javascript - 使用 html5 canvas 将图像剪辑成多边形的可重用函数

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:34:19 25 4
gpt4 key购买 nike

猜测帖子的标题可能需要编辑,但目前我不知道问题出在哪里。我已经在这里和其他地方阅读了类似问题的页面和答案。一个 Stack Overflow 的答案特别接近,但我不明白。

我想要一个函数,在 Canvas 上以所需的坐标绘制多边形,并用从文件加载的一些背景图像填充它们(足够大,不需要平铺)。三 Angular 形适合测试。显然我应该使用 drawImage 和剪辑,并给多边形一个边框,我可以为剪辑和描边重新使用相同的路径。显然我应该保持顺序

- define path
- save
- clip
- drawImage
- restore
- stroke.

另在某处读到,加载一次图像就足够了。 (如果你想让我引用所有这些假设的来源,我会寻找我在哪里看到它们。其中大部分在 Stack Overflow 上)

HTML 是空的

<body onload = "main ();"></body>

第一种方法,假装浏览器会等待图片加载:

var ctx, img;
var image_path = 'bg.jpg';

function main () {

var CANVAS_SIZE = 600;
var view_field_cnv = document.createElement ('canvas');
view_field_cnv.width = CANVAS_SIZE;
view_field_cnv.height = CANVAS_SIZE;
view_field_cnv.style.border = "1px solid";
document.body.appendChild (view_field_cnv);
ctx = view_field_cnv.getContext ('2d');

img = document.createElement ('img');
img.src = image_path;

place_triangle (0, 0);
place_triangle (300, 300);
place_triangle (500, 500);
place_triangle (0, 0);

}

function place_triangle (x, y) {

console.log (x, y);

ctx.beginPath ();
ctx.moveTo (x + 10, y);
ctx.lineTo (x + 110, y);
ctx.lineTo (x + 60, y + 40);
ctx.closePath ();

img = document.createElement ('img');
img.src = image_path;

ctx.save ();
ctx.clip ();
ctx.drawImage (img, x, y);
ctx.restore ();
ctx.stroke ();


}

绘制了所有三个三 Angular 形,但没有裁剪图像。

第二次尝试,在 image.onload 中使用 drawImage:

var ctx;
var image_path = 'bg.jpg';

function main () {

var CANVAS_SIZE = 600;
var view_field_cnv = document.createElement ('canvas');
view_field_cnv.width = CANVAS_SIZE;
view_field_cnv.height = CANVAS_SIZE;
view_field_cnv.style.border = "1px solid";
document.body.appendChild (view_field_cnv);
ctx = view_field_cnv.getContext ('2d');

place_triangle (0, 0);
place_triangle (300, 300);
place_triangle (500, 500);
place_triangle (0, 0);

}

function place_triangle (x, y) {

console.log (x, y);

var img;

ctx.beginPath ();
ctx.moveTo (x + 10, y);
ctx.lineTo (x + 110, y);
ctx.lineTo (x + 60, y + 40);
ctx.closePath ();

img = document.createElement ('img');
img.src = image_path;
img.onload = function () {

ctx.save ();
ctx.clip ();
ctx.drawImage (img, x, y);
ctx.restore ();
ctx.stroke ();
}

}

这个确实绘制了裁剪图像,但是只有一个三 Angular 形,最后一个。只是注释掉保存和恢复没有帮助。

所以,我不了解加载图像、保存、恢复以及可能还有一百万种其他事情。错误在哪里?

最佳答案

我看你已经了解了裁剪的基础知识:

  • 保存上下文,定义路径,剪辑,drawImage,恢复上下文。

  • 如果您希望描边与剪裁的图像稍微重叠,您可以在还原后描边。

  • 如果您不希望描边与剪裁的图像重叠,您可以在剪裁之前描边。

enter image description here

这是示例代码和演示:http://jsfiddle.net/m1erickson/p0fup425/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");

// image loader
// put the paths to your images in imageURLs[]
var imageURLs=[];
// push all your image urls!
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/norwayFlag.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/swedishFlag.jpg");

// the loaded images will be placed in images[]
var imgs=[];

var imagesOK=0;
loadAllImages(start);

function loadAllImages(callback){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
callback();
}
};
img.onerror=function(){alert("image load failed");}
img.crossOrigin="anonymous";
img.src = imageURLs[i];
}
}

function start(){

// the imgs[] array now holds fully loaded images
// the imgs[] are in the same order as imageURLs[]

// clip image#1
clippingPath([10,70,50,10,90,70],imgs[0],10,10);

// clip image#2
clippingPath([10,170,50,110,90,170],imgs[1],10,110);

// append the original images for demo purposes
document.body.appendChild(imgs[0]);
document.body.appendChild(imgs[1]);

}

function clippingPath(pathPoints,img,x,y){

// save the unclipped context
ctx.save();

// define the path that will be clipped to
ctx.beginPath();
ctx.moveTo(pathPoints[0],pathPoints[1]);
// this demo has a known number of polygon points
// but include a loop of "lineTo's" if you have a variable number of points
ctx.lineTo(pathPoints[2],pathPoints[3]);
ctx.lineTo(pathPoints[4],pathPoints[5]);
ctx.closePath();

// stroke the path
// half of the stroke is outside the path
// the outside part of the stroke will survive the clipping that follows
ctx.lineWidth=2;
ctx.stroke();

// make the current path a clipping path
ctx.clip();

// draw the image which will be clipped except in the clipping path
ctx.drawImage(img,x,y);

// restore the unclipped context (==undo the clipping path)
ctx.restore();
}


}); // end $(function(){});
</script>
</head>
<body>
<p>Images clipped inside triangular canvas paths</p>
<canvas id="canvas" width=150 height=200></canvas>
<p>Original Images</p>
</body>
</html>

关于javascript - 使用 html5 canvas 将图像剪辑成多边形的可重用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25701798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com