在 Canvas 中交换裁剪图像
Swapping Cropped Images in Canvas
我想交换图像中的两个圆形切口并交换它们的位置并将它们绘制到 canvas。但是,我在绘制第二个圆形图像时遇到了问题。有趣的是,在 second
中,如果您取消注释第一行,它会绘制该图像,否则,如果您将它放在函数的末尾,它不会绘制(至少在顶部)。如果我注释掉第一个函数,我就会得到要在 canvas 上绘制的图像。第一个函数总是在第二个函数之前执行。
function first() {
ctx.drawImage(imgBig, 0, 0);
ctx.beginPath();
ctx.arc(imgObj1.x + imgObj1.width / 2, imgObj1.y + imgObj1.width / 2, imgObj1.width / 2, 0, 6.28, false);
ctx.clip();
ctx.stroke(); // the outline of circle
ctx.closePath();
ctx.drawImage(imgBig, imgObj2.x, imgObj2.y, imgObj2.width, imgObj2.height, imgObj1.x, imgObj1.y, imgObj1.width, imgObj1.height);
function second() {
// ctx.drawImage(imgCuttingBoard, 0, 0); // this will draw over canvas
ctx.beginPath();
ctx.arc(imgObj2.x + imgObj2.width / 2, imgObj2.y + imgObj2.width / 2, imgObj2.width / 2, 0, 6.28, false);
ctx.clip();
ctx.closePath();
ctx.drawImage(imgCuttingBoard, imgObj1.x, imgObj1.y, imgObj1.width, imgObj1.height, imgObj2.x, imgObj2.y,
imgObj2.width, imgObj2.height); // this doesn't draw on top of the image (might be drawing underneath?)
// ctx.drawImage(imgCuttingBoard, 0, 0); // this will not draw over canvas here
}
假设您在尝试 drawImage
之前给了图像完全加载的时间。您确实使用了 image.onload
并等待图像加载?
那么你的问题很可能是剪裁...
context.clip
是累积的。如果将一个剪辑 (clip#1) 应用到 canvas,然后再应用另一个剪辑 (clip#2),则生成的剪辑区域是 clip#1 和 clip#2 的交集。生成的剪辑不是剪辑#2。
因此,如果您想撤消剪辑 #1 以便使用完整的剪辑 #2,则必须将第一个剪辑包装在 context.save
和 context.restore
中。
这里有一个稍微不同的方法,使用临时 canvas
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/faces%20no%20background.png";
function start(){
cw=canvas.width=img.width;
ch=canvas.height=img.height;
ctx.drawImage(img,0,0);
// do the swap
clipCircle(img,63.5,56,54,203,177);
clipCircle(img,203,177,54,63.5,56);
}
function clipCircle(img,sourceCX,sourceCY,r,newCX,newCY){
var c=document.createElement('canvas');
var cctx=c.getContext('2d');
c.width=2*r;
c.height=2*r;
// define an clipping circle
cctx.beginPath();
cctx.arc(r,r,r,0,Math.PI*2);
// draw the source into the temp canvas
cctx.drawImage(img,-sourceCX+r,-sourceCY+r);
// draw the temp canvas onto the main canvas
ctx.drawImage(c,newCX-r,newCY-r);
}
body{ background-color: ivory; }
canvas{border:1px solid red; margin:0 auto; }
<h4>Swapped clipping on canvas<br>(top-left swapped with bottom-center)</h4>
<canvas id="canvas" width=300 height=300></canvas>
<h4>Original Image</h4>
<img src='https://dl.dropboxusercontent.com/u/139992952/multple/faces%20no%20background.png'>
我想交换图像中的两个圆形切口并交换它们的位置并将它们绘制到 canvas。但是,我在绘制第二个圆形图像时遇到了问题。有趣的是,在 second
中,如果您取消注释第一行,它会绘制该图像,否则,如果您将它放在函数的末尾,它不会绘制(至少在顶部)。如果我注释掉第一个函数,我就会得到要在 canvas 上绘制的图像。第一个函数总是在第二个函数之前执行。
function first() {
ctx.drawImage(imgBig, 0, 0);
ctx.beginPath();
ctx.arc(imgObj1.x + imgObj1.width / 2, imgObj1.y + imgObj1.width / 2, imgObj1.width / 2, 0, 6.28, false);
ctx.clip();
ctx.stroke(); // the outline of circle
ctx.closePath();
ctx.drawImage(imgBig, imgObj2.x, imgObj2.y, imgObj2.width, imgObj2.height, imgObj1.x, imgObj1.y, imgObj1.width, imgObj1.height);
function second() {
// ctx.drawImage(imgCuttingBoard, 0, 0); // this will draw over canvas
ctx.beginPath();
ctx.arc(imgObj2.x + imgObj2.width / 2, imgObj2.y + imgObj2.width / 2, imgObj2.width / 2, 0, 6.28, false);
ctx.clip();
ctx.closePath();
ctx.drawImage(imgCuttingBoard, imgObj1.x, imgObj1.y, imgObj1.width, imgObj1.height, imgObj2.x, imgObj2.y,
imgObj2.width, imgObj2.height); // this doesn't draw on top of the image (might be drawing underneath?)
// ctx.drawImage(imgCuttingBoard, 0, 0); // this will not draw over canvas here
}
假设您在尝试 drawImage
之前给了图像完全加载的时间。您确实使用了 image.onload
并等待图像加载?
那么你的问题很可能是剪裁...
context.clip
是累积的。如果将一个剪辑 (clip#1) 应用到 canvas,然后再应用另一个剪辑 (clip#2),则生成的剪辑区域是 clip#1 和 clip#2 的交集。生成的剪辑不是剪辑#2。
因此,如果您想撤消剪辑 #1 以便使用完整的剪辑 #2,则必须将第一个剪辑包装在 context.save
和 context.restore
中。
这里有一个稍微不同的方法,使用临时 canvas
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/faces%20no%20background.png";
function start(){
cw=canvas.width=img.width;
ch=canvas.height=img.height;
ctx.drawImage(img,0,0);
// do the swap
clipCircle(img,63.5,56,54,203,177);
clipCircle(img,203,177,54,63.5,56);
}
function clipCircle(img,sourceCX,sourceCY,r,newCX,newCY){
var c=document.createElement('canvas');
var cctx=c.getContext('2d');
c.width=2*r;
c.height=2*r;
// define an clipping circle
cctx.beginPath();
cctx.arc(r,r,r,0,Math.PI*2);
// draw the source into the temp canvas
cctx.drawImage(img,-sourceCX+r,-sourceCY+r);
// draw the temp canvas onto the main canvas
ctx.drawImage(c,newCX-r,newCY-r);
}
body{ background-color: ivory; }
canvas{border:1px solid red; margin:0 auto; }
<h4>Swapped clipping on canvas<br>(top-left swapped with bottom-center)</h4>
<canvas id="canvas" width=300 height=300></canvas>
<h4>Original Image</h4>
<img src='https://dl.dropboxusercontent.com/u/139992952/multple/faces%20no%20background.png'>