如何填充多个画布图像的颜色?

时间:2015-01-16 10:01:02

标签: javascript html5 canvas html5-canvas

这是我第一次使用html5画布,但我还不知道它是如何工作的。

我的问题是,我必须修改画布中图像的颜色。如果只有一张图片,这很容易。但是,我会有不止一个,换句话说,重叠的图像。

为了进一步了解我的问题,我创建了一个插图。将只有2个图像文件,图像1和图像2:

enter image description here

这是我当前的代码(此处也有fiddle):

HTML:

<canvas id="canvas1" width="600" height="600"></canvas>

JS:

var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
var ctx2 = can.getContext('2d');


ctx.fillStyle = 'yellow'; // background color. box in the middle is transparent. try changing this to see the effect
ctx.fillRect(40,0,250,300); // not sure if there's other way to fill in the tranparent area. but I created a box behind the image

var img = new Image();
img.onload = function() {
    ctx.drawImage(img, 0, 0);
}

img.src = "http://s7.postimg.org/aruxhs8mz/pink.png"; //image 1


// I want to fill in the paw image too
/*ctx2.fillStyle = 'purple'; 
ctx2.fillRect(40,0,500,500); */

//should I declare something like this again?

var img2 = new Image();
img2.onload = function() {
    ctx2.drawImage(img2, 0, 0);
}

img2.src = "http://s7.postimg.org/69smposl7/paw.png"; //image 2
//paw initially colored light blue. i would like to customize the color of this too

我应该能够在中间填充爪子图像,而不仅仅是主图像。怎么做?

我创造了一个小提琴,只是为了启发你的问题。

希望有人能帮助我提出任何建议。

非常感谢!

3 个答案:

答案 0 :(得分:3)

您可以使用合成来完成任务。

enter image description here enter image description here

合成告诉画布在画布上绘制其他新图形(像素)时要做什么。

在您的情况下,3种合成模式对学习很有用。

来源合作

合成的默认方法是“source-over”,其中在现有像素上绘制新绘图。

// first draw a blue destination rectangle
ctx.fillStyle='blue';
ctx.fillRect(30,30,50,50);

// second draw a red source rectangle
ctx.fillStyle='red';
ctx.fillRect(60,60,50,50);

enter image description here然后enter image description here结果为enter image description here

Source-atop Compositing

'source-atop'合成将仅在新像素与现有画布像素重叠的位置绘制新像素。

// first draw a blue destination rectangle
ctx.fillStyle='blue';
ctx.fillRect(30,30,50,50);

// set compositing to 'source-atop'
// (the new red pixels will only be drawn where
//  they overlap the existing blue pixels)
ctx.globalCompositeOperation='source-atop';

// second draw a red source rectangle
// (red will overwrite only where it overlapped the blue)
ctx.fillStyle='red';
ctx.fillRect(60,60,50,50);

enter image description here然后enter image description here结果为enter image description here

目的地合成

'destination-over'合成将在现有画布像素下绘制新像素。

// first draw a blue destination rectangle
ctx.fillStyle='blue';
ctx.fillRect(30,30,50,50);

// set compositing to 'source-atop'
// (the new red pixels will only be drawn where
//  they overlap the existing blue pixels)
ctx.globalCompositeOperation='destination-over';

// second draw a red source rectangle
// (red will appear under the blue)
ctx.fillStyle='red';
ctx.fillRect(60,60,50,50);

enter image description here然后enter image description here结果为enter image description here

以下是如何使用合成来改变爪子的颜色。

  1. 清除画布。您无法直接更改以前在画布上绘制的任何内容的颜色,因此画布的典型工作流程是将其删除并重新绘制新位置和项目。颜色。

  2. 绘制爪子图像。

  3. 将合成设置为source-atop,这样只会在现有爪子像素存在的地方绘制新图纸。

  4. 使用fillStyle&amp ;;填充您的新爪子颜色的画布fillRect。这会导致您的爪子重新着色,因为新着色的矩形像素仅出现在您的爪子像素当前存在的位置。

  5. 将合成设置为destination-over,以便在现有像素下绘制新图纸。

  6. 填充黄色框。你的爪子不会被覆盖,因为新的(黄色)像素会被“画在你的爪子下面”。

  7. 将合成设置恢复为默认source-over,以便在现有图纸上绘制新图纸。

  8. 在中心绘制透明的框架。您的爪子和黄色背景将通过框架的透明中​​心显示。

  9. 这是示例代码和演示:

    var can = document.getElementById('canvas1');
    var ctx = can.getContext('2d');
    var ctx2 = can.getContext('2d');
    
    var images=[];
    var urls=[];
    urls.push('http://s7.postimg.org/aruxhs8mz/pink.png');
    urls.push('http://s7.postimg.org/69smposl7/paw.png');
    var imgCount=urls.length;
    
    document.getElementById('recolor').onclick=function(){
      redrawWithNewPawColor();
    };
    
    for(var i=0;i<urls.length;i++){
      images[i]=new Image();
      images[i].onload=myOnload;
      images[i].src=urls[i];
    }
    function myOnload(){
      imgCount--;
      if(imgCount>0){return;}
      start();
    }
    function start(){
      redrawWithNewPawColor()
    }
    
    function drawWithRecoloredPaw(newPawColor){
    
      // clear the canvas
      ctx.clearRect(0,0,can.width,can.height);
    
      // draw the paw
      ctx.drawImage(images[1], 0, 0);  
    
      // set compositing to source-atop
      // so only existing pixels will be overwritten
      ctx.globalCompositeOperation='source-atop';
      // fill with new color
      ctx.fillStyle=newPawColor;
      // Because of compositing, only the paw is being color filled
      ctx.fillRect(0,0,can.width,can.height);
    
      // set compositing to destination-over
      // so new pixels will be draw behind existing (paw) pixels
      ctx.globalCompositeOperation='destination-over';
      // change the fill color to yellow
      ctx.fillStyle='yellow';
      // fill the yellow box
      ctx.fillRect(40,0,250,300);   
    
      // set compositing to the default of source-over
      ctx.globalCompositeOperation='source-over';
      // draw the transparent frame
      ctx.drawImage(images[0],0,0);
    
    }
    
    function redrawWithNewPawColor(){
      drawWithRecoloredPaw(randomColor());
    }
    
    function randomColor(){ 
      return('#'+Math.floor(Math.random()*16777215).toString(16));
    }
    body{ background-color: ivory; padding:10px; }
    #canvas{border:1px solid red;}
    <button id='recolor'>Recolor Paw</button>
    <br>
    <canvas id="canvas1" width=600 height=600></canvas>

答案 1 :(得分:1)

问题是画布不允许你调整图像,但你可以在不透明度为0.5的爪子上创建一个块而不是再次填充透明部分,你也可以使用: http://www.w3schools.com/tags/canvas_globalcompositeoperation.asp

答案 2 :(得分:1)

如果图片位于您自己的网络文件夹中,您可以将其与img标签一起使用,并将数据更改为

非常类似于W3S示例Changing image in canvas

在此步骤之后,只需使用新数据重新绘制画布

如果图片来自其他来源,由于安全原因

,这将无效