Search code examples
javascriptwebdata-uri

Merge two dataURIs to create a single image


I want to generate images consisting of a label and an icon. The label part is going to vary a lot (50-100) while there are about 10 icons. I would like to make the final images in a modular way by splitting the final image in two parts, a label image and an icon image. I will build a service that returns dataURI for the labels while the icon dataURIs will be embedded in the page. Then I would like to combine these two different dataURIs to create a single dataURI representing a combined image.

How can I do this on the client side?


Solution

  • You can create images using your data uris and then draw a new image that includes them using canvas. Here's a simple example:

    var nloaded = 0;
    function checkload(event) {
      nloaded++;
      if (nloaded < 2) {
        return;
      }
      
      var canvas = document.querySelector('canvas');
      var context = canvas.getContext('2d');
      context.drawImage(image1, 0, 0, 50, 50);
      context.drawImage(image2, 50, 50, 100, 100);
    
      var combined = new Image;
      combined.src = canvas.toDataURL('data/gif');
      
      document.body.appendChild(combined);
    }
    
    var image1 = new Image;
    image1.onload = checkload;
    image1.src = 'data:image/gif;base64,R0lGODdhAgACALMAAAAAAP///wAAAAAAAP8AAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAAgACAAAEAxBJFAA7';
    
    
    var image2 = new Image;
    image2.onload = checkload;
    image2.src = 'data:image/gif;base64,R0lGODdhAgACALMAAAAAAP///wAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAAgACAAAEA5BIEgA7';
    canvas {
        display: none;
    }
    <canvas width=100 height=100></canvas>

    .

    Once you have the images loaded from the data URI and combined using the drawImage commands of the canvas context you can use the canvas to create a new image like:

    var combined = new Image;
    combined.src = canvas.toDataURL('data/gif');
    

    Unfortunately this won't work in IE8.