画布中的反向剪辑

时间:2014-03-04 10:01:02

标签: html5 html5-canvas

我想剪辑html5画布,以便我可以按照下面的图像获得绘图结果。

我想实现剪辑路径,以便所有绘图仅在黑色区域执行。

enter image description here

2 个答案:

答案 0 :(得分:4)

方法1

假设白色区域是透明的而黑色是不透明的,那么您可以使用复合模式:

ctx.globalCompositeOperation = 'source-in';
... draw graphics on top - only solid color will be affected ...
ctx.globalCompositeOperation = 'source-over';      // reset to default mode

<强> A demo fiddle for this here

方法2

另一种更简单的方法是简单地用您需要的图形填充画布,然后使用clearRect()来表示您想要透明的区域。

此操作相当快,因此不应有任何闪烁(如果您可以通过单个requestAnimationFrame调用触发此操作)。

<强> A demo fiddle with clearRect
A demo fiddle with clearRect + requestAnimationFrame

请注意,调用rAF使代码异步,但使用它的目的是你的绘制操作在帧更新中同步,因此闪烁将被删除(如果由于某种原因你应该对此产生问题)。

方法3

通过对rect()的一系列调用,创建要保留的区域周围的矩形区域。使用clip()作为剪贴蒙版的设置。

如果非裁剪区域按特定顺序排列,或者您必须定义许多区域,此技术效果最佳。

请记住首先翻译画布0.5像素,并仅使用矩形的整数值。

方法4

手动解析像素缓冲区以填充满足要求的区域中的像素,例如仅非透明像素。

请注意,这可能是最慢的方法,它受CORS限制的影响(如果您首先在画布上绘制外部图像),如果您想要填充形状,图像,渐变等,则会更加繁琐如果您可能更喜欢从屏幕外的画布复制而来。

还有其他方法可以使用不同的复合模式和绘制顺序来实现相同的结果,但我将其留下来,因为它应该涵盖大多数场景。

答案 1 :(得分:0)

您可以使用分层来满足您的需求:

  • 制作一张全黑透明的图像副本
  • 在画布上绘制原始图像
  • 绘制您想要的形状
  • 在顶部绘制透明图片

演示:http://jsfiddle.net/m1erickson/dFRUf/

enter image description here

此功能会创建一个临时画布,其指定的颜色范围变为透明:

function makeImageTransparentByColor(image,r1,r2,g1,g2,b1,b2){
    // create a temporary canvas and draw the image on the canvas 
    var bk=document.createElement("canvas");
    var bkCtx=bk.getContext("2d");
    bk.width=image.width;
    bk.height=image.height
    bkCtx.drawImage(image,0,0);
    // get the pixel array from the canvas
    var imgData=bkCtx.getImageData(0,0,bk.width,bk.height);
    var data=imgData.data;
    // loop through each pixel and make every pixel transparent
    // that is between r1-r2, g1-g2 and b1-b2
    for(var i=0;i<data.length;i+=4){
        var r=data[i];
        var g=data[i+1];
        var b=data[i+2]
        if(r>=r1 && r<=r2 && g>=g1 && g<=g2 && b>=b1 && b<=b2){
            data[i]=0;
            data[i+1]=0;
            data[i+2]=0;
            data[i+3]=0;
        }
    }
    // put the modified pixels back on the canvas
    bkCtx.putImageData(imgData,0,0);
    // return the canvas with transparent image
    return(bk);
}