Skip to content Skip to sidebar Skip to footer

How To DrawImage Behind All Other Content On A Canvas?

I have a canvas, and I want to use drawImage to draw an image behind the current content on the canvas. Due to the fact that there is content already on the canvas (I'm using Liter

Solution 1:

Yes you can just use globalCompositeOperation destination-over, but note that your first image needs some transparency, otherwise, you will obviously not see anything :

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 = "https://picsum.photos/200/200";
<canvas id="c" width="200" height="200"></canvas>

Solution 2:

Sorry about the previous post, I didn't properly read your post

Perhaps you could save the canvas, draw your image, and then reload the old content on top of your drawn image? Here's some JS psuedocode:

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

Solution 3:

You can use KonvaJS. And then use layers for it.

<!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>

Solution 4:

A simple solution would be to use another canvas behind the first one.

Normally canvas pixels are initialized to transparent black and therefore are perfectly see-through.

If your first canvas is created opaque instead the only other option I can think to is

  1. create a temporary canvas of the same size
  2. draw your image in this temporary canvas
  3. get the ImageData object of both the temporary canvas and of the original canvas
  4. copy from the temporary canvas to the original canvas only where the original canvas is not set at the background color

In code:

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

this approach however will have a lower quality if the original canvas graphics has been drawn with antialiasing or if pixels of the background color are also used in the image (e.g. an object on #FFF white background where object highlights are also #FFF). Another problem is if the background color is not a perfectly uniform RGB value (this will happen if the image has been compressed with a lossy algorithm like jpeg).

All these problems could be mitigated with more sophisticated algorithms like range matching, morphological adjustments and color-to-alpha conversions (basically the same machinery used for chroma-keying).


Post a Comment for "How To DrawImage Behind All Other Content On A Canvas?"