Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 915
maulik13 Avatar asked Aug 19 '15 13:08

maulik13


People also ask

How to combine multiple images into a single image?

Using this tool, it is possible to easily combine multiple images into a single image. Instructions for Use. First, click "Open Image File" in the main menu to load an image file. ... 1. Combine 3 images vertically 2. Create a new line and combine the 4th image vertically 3. Combine the 5th image vertically 4. Combine the 6th image vertically.

What are the different types of merger images?

Merge images has three modes. The first is vertical merge. The picture is merged into a picture from top to bottom. The second is horizontal merging, which is merged into a picture from left to right. The third is a fixed number of columns. If the number of fixed columns is 3, 3 pictures are merged from left to right.

How to merge 3 pictures to get a rectangular picture?

The third is a fixed number of columns. If the number of fixed columns is 3, 3 pictures are merged from left to right. Then the next line, then merge 3 pictures from left to right. Finally it will become a rectangular picture.

How do I combine 3 images in Photoshop?

Combine 3 images horizontally 2. Create a new line and combine the 4th image horizontally 3. Combine the 5th image horizontally 4. Combine the 6th image horizontally 1. Combine 3 images vertically


2 Answers

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.

like image 64
mrmcgreg Avatar answered Oct 07 '22 00:10

mrmcgreg


Example using an array of image objects containing URI src and x, y offsets:

var images = [
   { src: 'data:image/gif;base64,R0lGODdhAgACALMAAAAAAP///wAAAAAAAP8AAAAAAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAAgACAAAEAxBJFAA7', x: 0, y: 0 },
   { src: 'data:image/gif;base64,R0lGODdhAgACALMAAAAAAP///wAAAAAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAAgACAAAEA5BIEgA7', x: 20, y: 20 },
];

var canvas = document.createElement('canvas');
var destination = document.getElementById('canvas');

Promise.all(images.map(imageObj => add2canvas(canvas, imageObj)))
    .then(() => destination.append(canvas));

function add2canvas(canvas, imageObj) {
   return new Promise( (resolve, reject) => {
      if (!imageObj || typeof imageObj != 'object') return reject();
      var image = new Image();
      image.onload = function () {
          canvas.getContext('2d')
                .drawImage(this, imageObj.x || 0, imageObj.y || 0);
          resolve();
      };

      image.src = imageObj.src;
   });
}

Some more bells/whistles... function to generate a composite png:

  function mergeImageURIs(images) {
      return new Promise( (resolve, reject) => {
          var canvas = document.createElement('canvas');
          canvas.width = 1000; // desired width of merged images
          canvas.height = 1000; // desired height of merged images
          Promise.all(images.map(imageObj => add2canvas(canvas, imageObj))).then(() => resolve(canvas.toDataURL('image/png'), reject));
      });
  }

  function add2canvas(canvas, imageObj) {
    return new Promise( (resolve, reject) => {
       if (!imageObj || typeof imageObj != 'object') return reject();
       var x = imageObj.x && canvas.width ? (imageObj.x >=0 ? imageObj.x : canvas.width + imageObj.x) : 0;
       var y = imageObj.y && canvas.height ? (imageObj.y >=0 ? imageObj.y : canvas.height + imageObj.y) : 0;
       var image = new Image();
       image.onload = function () {
           canvas.getContext('2d').drawImage(this, x, y);
           resolve();
       };

       image.src = imageObj.src;
    });
  }
like image 39
TennisVisuals Avatar answered Oct 07 '22 00:10

TennisVisuals