如何为多张 canvas 图片填充颜色?

How to fill color of more than one canvas image?

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

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

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

这是我当前的代码(这里也有 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

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

我创建了一个 fiddle 只是为了让您了解我的问题。

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

非常感谢!

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

如果图像在您自己的网络文件夹中,您可以将其与 img 标签一起使用并获取数据并对其进行更改

很像 W3S 示例 Changing image in canvas

完成这一步后,只需用新数据重新绘制 canvas

出于安全原因,如果图像来自其他来源,这将不起作用

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

合成告诉 canvas 在 canvas 上绘制额外的新绘图(像素)时要做什么。

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

Source-over 合成

默认的合成方法是 '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);

然后 结果

Source-atop 合成

'source-atop' 合成将仅在新像素与现有 canvas 像素重叠的地方绘制新像素。

// 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);

然后 结果

Destination-over 合成

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

// 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);

然后 结果

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

  1. 清除canvas。您不能直接更改之前在 canvas 上绘制的任何内容的颜色,因此 canvas 的典型工作流程是擦除它并在新位置和颜色中重新绘制项目。

  2. 画爪子图像。

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

  4. 使用 fillStylefillRect 用您的新爪子颜色填充 canvas。这会导致您的爪子重新着色,因为新着色的矩形像素只会出现在您的爪子像素当前存在的位置。

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

  6. 填写黄色框。你的爪子不会被覆盖,因为新的(黄色)像素将被绘制 "under" 你的爪子。

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

  8. 绘制中间透明的框架。您的爪子和黄色背景会透过框架的透明中​​心显示出来。

这是示例代码和演示:

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>