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

Javascript 如何在画布上的所有其他内容后面绘制图像?,javascript,html,canvas,Javascript,Html,Canvas,我有一个画布,我想使用drawImage在画布上当前内容的后面绘制一个图像 由于画布上已经有内容(我正在使用canvas创建一个包含图像的画布,因此我不能首先真正绘制图像),因此在渲染其余内容之前,我不能使用drawImage 是否可以在画布上的所有其他内容后面绘制图像?很抱歉,我没有正确阅读您的文章 也许您可以保存画布,绘制图像,然后将旧内容重新加载到绘制图像的顶部?下面是一些JS伪代码: var imgData=ctx.getImageData(0,0,canvas.width,canvas

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

由于画布上已经有内容(我正在使用canvas创建一个包含图像的画布,因此我不能首先真正绘制图像),因此在渲染其余内容之前,我不能使用
drawImage


是否可以在画布上的所有其他内容后面绘制图像?

很抱歉,我没有正确阅读您的文章

也许您可以保存画布,绘制图像,然后将旧内容重新加载到绘制图像的顶部?下面是一些JS伪代码:

var imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
ctx.drawImage('Your Image Watermark Stuff');
ctx.putImageData(imgData,0,0);
是的,您可以在上使用
目的地,但请注意,您的第一张图像需要一定的透明度,否则,您将明显看不到任何内容:

var img1=新图像();
var img2=新图像();
var=0;
var imageLoad=函数(){
如果(++加载==2){
draw();
}
};
img1.onload=img2.onload=imageLoad;
var draw=function(){
var ctx=c.getContext('2d');
ctx.drawImage(img1,100100);
//请稍等片刻,然后再绘制背景图像
setTimeout(函数(){
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";

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

通常画布像素初始化为透明黑色,因此完全透明

如果你的第一块画布是不透明的,那么我唯一能想到的是

  • 创建相同大小的临时画布
  • 在此临时画布中绘制图像
  • 获取临时画布和原始画布的ImageData对象
  • 仅当原始画布未设置为背景色时,才从临时画布复制到原始画布
  • 代码:

    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);
    
    var tmpcanvas=document.createElement(“画布”);
    tmpcanvas.width=canvas.width;
    tmpcanvas.height=canvas.height;
    var temp_ctx=tmpcanvas.getContext(“2d”);
    // ... 将图像绘制到临时上下文中。。。
    var temp_idata=temp_ctx.getImageData(0,0,canvas.width,canvas.height);
    var temp_data=temp_idata.data;
    //访问原始画布像素
    var ctx=canvas.getContext(“2d”);
    var idata=ctx.getImageData(0,0,canvas.width,canvas.height);
    var数据=idata.data;
    //找到背景色(这里我将使用左上角的第一个像素)
    var br_r=data[0],bg_g=data[1],bg_b=data[2];
    //用临时图像中的像素替换所有背景像素
    对于(var i=0,n=canvas.width*canvas.height*4;i您可以使用。然后为其使用层

    <!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>
    
    
    Konva Rect演示
    身体{
    保证金:0;
    填充:0;
    溢出:隐藏;
    背景色:#f0;
    }
    变量宽度=window.innerWidth;
    var height=window.innerHeight;
    var阶段=新Konva.阶段({
    容器:'容器',
    宽度:宽度,
    高度:高度
    });
    var layer=新Konva.layer();
    var imageObj=新图像();
    imageObj.onload=函数(){
    var baseImage=新的Konva.Image({
    x:50,
    y:50,
    宽度:宽度,
    高度:高度,,
    图像:图像
    });
    //将形状添加到层中
    层。添加(rect);
    //将层添加到舞台
    阶段。添加(层);
    };
    imageObj.src='url to your image'
    
    水印的唯一用途是位于非水印内容之上behind@slash197请忽略这一事实,即它是一个水印-有可能将其插入画布上所有其他内容的后面吗?不,没有,画布没有这样的内存。您不能将内容插入页面上其他内容的后面-当画一条线时,会出现插入图形或绘制图像时,图形处于“锁定”状态进入画布-将画布想象为每次向画布添加内容时将所有层合并为一个。很遗憾,你不能在其他内容后面添加内容。@THINKER啊,我现在明白了。我想那是做不到的:/我意识到这是可以做到的,但这不是我想做的-我想插入图像e隐藏在所有其他内容后面,而不是使其透明。哦,对不起,我只是阅读了水印并跳到了它。是的,这是我最后做的。谢谢你的帮助!这与我的帖子有什么不同吗?我真的很喜欢这个答案,但我刚刚意识到它并没有得到广泛的支持。@wateriswet-hum所有支持html5的浏览器都支持它画布。你确定吗?如果是,你应该更新与答案链接的MDN文档。@wateriswet我将告诉你如何阅读它:“基本支持”是每个浏览器的“是”。“混合模式”是“?”对于很多浏览器来说,destination over是一种复合模式,它拥有所有浏览器的基本支持。一些早期的实现和Safari仍然缺少一些混合模式,对此答案并不关心。