javascripthtmlcanvasdata-url

How do I extract a portion of an image in canvas and use it as background image for a div?


This is how my code looks:

document.addEventListener('DOMContentLoaded', function () {
        var canvas = document.querySelector('canvas');
        var ctx = canvas.getContext("2d");
        var imageData = ctx.getImageData(0, 0, 300, 300);
        var tile = {
                        'id': 1,
                        'data': imageData,
                        'dataUrl': imageData.toDataUrl()
                    };
        var div = document.createElement('div');
                div.classList.add('tile');
                grid.appendChild(div);
                div.style.backgroundImage = ('url(' + tile.dataUrl + ')');
});

I'm trying to extract portion of the image on canvas, from (0,0) with height and width 300px, and convert that imageData object into a dataUrl to be used as a background of a div.

I get an error: imageData.toDataUrl() is not a function. How can I achieve this?

Thanks in advance!


Solution

  • toDataURL is an HTMLCanvasElement method you have to call it from the canvas element itself.

    You could draw back your resulted imageData to the canvas after you changed its size to the wanted one, but the easiest solution is to use a second, off-screen canvas, where you will draw the first canvas thanks to the context.drawImage method:

    // The crop function
    var crop = function(canvas, offsetX, offsetY, width, height, callback) {
      // create an in-memory canvas
      var buffer = document.createElement('canvas');
      var b_ctx = buffer.getContext('2d');
      // set its width/height to the required ones
      buffer.width = width;
      buffer.height = height;
      // draw the main canvas on our buffer one
      // drawImage(source, source_X, source_Y, source_Width, source_Height, 
      //  dest_X, dest_Y, dest_Width, dest_Height)
      b_ctx.drawImage(canvas, offsetX, offsetY, width, height,
                      0, 0, buffer.width, buffer.height);
      // now call the callback with the dataURL of our buffer canvas
      callback(buffer.toDataURL());
    };
    
    
    // #main canvas Part
    
    var canvas = document.getElementById('main');
    var img = new Image();
    img.crossOrigin = "Anonymous";
    
    img.onload = function() {
      canvas.width = this.width;
      canvas.height = this.height;
      canvas.getContext('2d').drawImage(this, 0, 0);
      // set a little timeout before calling our cropping thing
      setTimeout(function() {
        crop(canvas, 100, 70, 70, 70, callback)
      }, 1000);
    };
    
    img.src = "https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png";
    
    // what to do with the dataURL of our cropped image
    var callback = function(dataURL) {
      document.body.style.backgroundImage = 'url(' + dataURL + ')';
    }
    <canvas id="main" width="284" width="383"></canvas>