如何在画布上的所有其他内容后面绘制图像?

时间:2016-05-21 06:35:34

标签: javascript html html5 canvas

我有画布,我想使用drawImage在画布上的当前内容后面绘制图像。

由于画布上已有内容(我使用Literally Canvas创建包含图像的画布,因此我无法先绘制图像),我无法使用drawImage在我呈现其余内容之前。

是否有可能drawImage支持画布上的所有其他内容?

4 个答案:

答案 0 :(得分:2)

对于上一篇文章感到抱歉,我没有正确阅读您的帖子

也许您可以保存画布,绘制图像,然后在绘制的图像上重新加载旧内容?这里有一些JS伪代码:

var imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
ctx.drawImage('Your Image Watermark Stuff');
ctx.putImageData(imgData,0,0);

答案 1 :(得分:2)

是的,您可以使用globalCompositeOperation destination-over,但请注意您的第一张图片需要一些透明度,否则您显然看不到任何内容:



var img1 = new Image();
var img2 = new Image();

var loaded = 0;
var imageLoad = function(){
   if(++loaded == 2){
     draw();
     }
   };
img1.onload = img2.onload = imageLoad;

var draw = function(){
  var ctx = c.getContext('2d');
  ctx.drawImage(img1, 100,100);
  // wait a little bit before drawing the background image
  setTimeout(function(){
    ctx.globalCompositeOperation = 'destination-over';
    ctx.drawImage(img2, 0,0);
    }, 500);
  }
img1.src = "https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png";
img2.src = "http://lorempixel.com/200/200";

<canvas id="c" width="200" height="200"></canvas>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

您可以使用KonvaJS。然后使用图层。

<!DOCTYPE html>
<html>

<head>
  <script src="https://cdn.rawgit.com/konvajs/konva/0.13.0/konva.min.js"></script>
  <meta charset="utf-8">
  <title>Konva Rect Demo</title>
  <style>
    body {
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #F0F0F0;
    }
  </style>
</head>

<body>
  <div id="container"></div>
  <script>
    var width = window.innerWidth;
    var height = window.innerHeight;

    var stage = new Konva.Stage({
      container: 'container',
      width: width,
      height: height
    });

    var layer = new Konva.Layer();
    var imageObj = new Image();
    imageObj.onload = function() {
      var baseImage = new Konva.Image({
        x: 50,
        y: 50,
        width: width,
        height: height,
        image: image
      });

      // add the shape to the layer
      layer.add(rect);

      // add the layer to the stage
      stage.add(layer);
    };
    imageObj.src = 'url to your image'
  </script>

</body>

</html>

答案 3 :(得分:0)

一个简单的解决方案是在第一个后面使用另一个画布。

通常情况下,画布像素会初始化为透明黑色,因此非常透明。

如果您的第一个画布是不透明的,那么我能想到的唯一其他选项是

  1. 创建一个大小相同的临时画布
  2. 在此临时画布中绘制图像
  3. 获取临时画布和原始画布的ImageData对象
  4. 仅将原始画布设置为背景颜色
  5. ,从临时画布复制到原始画布

    在代码中:

    var tmpcanvas = document.createElement("canvas");
    tmpcanvas.width = canvas.width;
    tmpcanvas.height = canvas.height;
    var temp_ctx = tmpcanvas.getContext("2d");
    
    // ... draw your image into temporary context ...
    
    var temp_idata = temp_ctx.getImageData(0, 0, canvas.width, canvas.height);
    var temp_data = temp_idata.data;
    
    // Access the original canvas pixels
    var ctx = canvas.getContext("2d");
    var idata = ctx.getImageData(0, 0, canvas.width, canvas.height);
    var data = idata.data;
    
    // Find the background color (here I'll use first top-left pixel)
    var br_r = data[0], bg_g = data[1], bg_b = data[2];
    
    // Replace all background pixels with pixels from temp image
    for (var i=0,n=canvas.width*canvas.height*4; i<n; i+=4) {
        if (data[i] == bg_r && data[i+1] == bg_g && data[i+2] == bg_b) {
            data[i] = tmp_data[i];
            data[i+1] = tmp_data[i+1];
            data[i+2] = tmp_data[i+2];
            data[i+3] = tmp_data[i+3];
        }
    }
    
    // Update the canvas
    ctx.putImageData(idata, 0, 0);
    

    如果使用抗锯齿绘制原始画布图形,或者如果图像中也使用了背景颜色的像素,则此方法的质量会降低(例如#FFF白色背景上的对象,其中对象高亮也是#FFF )。另一个问题是如果背景颜色不是完全一致的RGB值(如果图像是使用像jpeg这样的有损算法压缩的话,就会发生这种情况。)

    所有这些问题都可以通过更复杂的算法来缓解,例如范围匹配,形态调整和颜色到alpha转换(基本上与用于色度键控的机器相同)。