如何避免在HTML5画布中着色特定颜色

时间:2014-07-09 15:45:10

标签: javascript html5 canvas

我有一个画布可以导入各种黑白图片,并希望它能使笔画不会在黑色像素上着色。现在,刷子效果完成:

    var ctx = canvas.getContext('2d');
    ...
    ctx.beginPath();
    //xy being the mouse coordinates, retrieved earlier. 
    ctx.arc(xy[0], xy[1], ctx.lineWidth/2, 0, 2*Math.PI, true);
    ctx.closePath();
    ctx.fill();

这是我想要实现的效果的一个例子。

Depiction of desired effect

1 个答案:

答案 0 :(得分:2)

[由提问者提供新信息更新]

Canvas尚不支持颜色混合,因此您可以使用getImageData

来实现效果

context.getImageData获取一个表示红色,绿色,蓝色和&的数组。画布上每个像素的alpha值。

您可以使用这些像素阵列将图像上的白色像素替换为上面的笔划像素。

  • 获取笔画的像素数组
  • 获取图像的像素数组
  • 将每个笔划像素与每个图像像素进行比较
  • 如果笔划超过白色像素,请将白色像素替换为笔触颜色像素

enter image description here

注意:

Black&白色图像通常是灰度图像,实际上不是纯黑色和白色图像。要替换“白色”像素,您必须测试图像像素以获得更广泛的rgb组合。白色像素倾向于具有更高的rgb颜色值的总和,因此您可以测试r + b + g> 600(或您期望的“白色”截止值)。

要使用getImageData,画布上绘制的图像必须与网页位于同一个域中,否则getImageData将因安全违规而失败。这可能需要您将用户图像上载到服务器并将其传送回网页。或者,您可以在支持它的客户端上使用FileReader,以允许用户将图像从其本地文件系统加载到网页。

以下是示例代码和演示:http://jsfiddle.net/m1erickson/26N7S/

<!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");

    var imgDataImage,imgDataStroke,dataImage,dataStroke;

    var img=new Image();
    img.crossOrigin="anonymous";
    img.onload=start;
    img.src="https://dl.dropboxusercontent.com/u/139992952/multple/BW.gif";
    function start(){

        canvas.width=img.width+100;
        canvas.height=img.height+100;

        drawStroke(ctx);
        imgDataStroke=ctx.getImageData(0,0,canvas.width,canvas.height);
        dataStroke=imgDataStroke.data;

        ctx.clearRect(0,0,canvas.width,canvas.height);
        drawImage();
        imgDataImage=ctx.getImageData(0,0,canvas.width,canvas.height);
        dataImage=imgDataImage.data;

        for(var i=0;i<dataStroke.length;i+=4){

            if(dataStroke[i+3]<200){
                // not under stroke, no changes to image
            }else if(dataImage[i+3]<200){
                // is under stroke, but not over image
                // so replace the image pixel with the color of the stroke
                dataImage[i+0]=dataStroke[i+0];
                dataImage[i+1]=dataStroke[i+1];
                dataImage[i+2]=dataStroke[i+2];
                dataImage[i+3]=dataStroke[i+3];
            }else if(dataImage[i]+dataImage[i+1]+dataImage[i+2]>150){
                // this image pixel is under the stroke and is "blackish", 
                // so replace the image pixel with the color of the stroke
                dataImage[i+0]=dataStroke[i+0];
                dataImage[i+1]=dataStroke[i+1];
                dataImage[i+2]=dataStroke[i+2];
                dataImage[i+3]=dataStroke[i+3];
            }else{
                // the pixel is under the stroke but is not "blackish",
                // so no changes to image
            }

        }

        ctx.putImageData(imgDataImage,0,0);
    }

    function drawImage(){
        ctx.drawImage(img,50,50);
    }

    function drawStroke(ctx){
        ctx.lineCap="round";
        ctx.lineWidth=15;
        ctx.strokeStyle="lightcoral";
        ctx.beginPath();
        ctx.moveTo(75,25);
        ctx.lineTo(canvas.width-75,canvas.height-25);
        ctx.stroke();
    }

}); // end $(function(){});
</script>
</head>
<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>