Merge Image using Javascript

Viewed 82619

Is it possible to merge pictures using javascript?

For example, if you have 2 rectangle .jpg or .png images files of the same size, is it possible that you can align it side by side and produce a merged copy of the two in a new .jpg or .png image file?

5 Answers

Updating this for 2019/2020+: there's an awesome npm package for this called merge-images

And its usage is very simple!

import mergeImages from 'merge-images';
 
mergeImages(['/body.png', '/eyes.png', '/mouth.png'])
  .then(b64 => document.querySelector('img').src = b64);
  // data:image/png;base64,iVBORw0KGgoAA...

You can further customize it with positioning, opacity (both per-image) and the output's dimensions!

(I'm not related to this package in any way, I just wasted 3 days getting html2canvas to work and then found this lifesaver!)

I know this is an old post, but I ran across it searching for a solution to this question, myself. Even moreso, I wanted to be able to upload the images that should be used (without needing to rely on server-side logic).

I've created a fiddle (http://jsfiddle.net/davidwalton/4pjreyfb/6/ ) that builds on this:

How to make a simple image upload using Javascript/HTML

I then added Huỳnh Quốc Phong's logic above (Merge Image using Javascript):

HTML:

<input class="file1" type="file" data-image-selector=".image1" />
<input class="file2" type="file" data-image-selector=".image2" />
<br />
<img class="image1 hidden" alt="medium image 1" />
<img class="image2 hidden" alt="medium image 2" />
<br />
<input class="btn-merge" type="button" value="Merge!" />
<br />
<img class="merged-image hidden" alt="merged image" />
<canvas id="canvas" class="hidden"></canvas>

JS:

$('.file1, .file2').on('change', function() {
  var reader = new FileReader(),
    imageSelector = $(this).data('image-selector');

  if (this.files && this.files[0]) {
    reader.onload = function(e) {
      imageIsLoaded(e, imageSelector)
    };
    reader.readAsDataURL(this.files[0]);
  }
});

$('.btn-merge').on('click', merge);

function imageIsLoaded(e, imageSelector) {
  $(imageSelector).attr('src', e.target.result);
  $(imageSelector).removeClass('hidden');
};

function merge() {
  var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d'),
    imageObj1 = new Image(),
    imageObj2 = new Image();

  imageObj1.src = $('.image1').attr('src');
  imageObj1.onload = function() {
    ctx.globalAlpha = 1;
    ctx.drawImage(imageObj1, 0, 0, 328, 526);
    imageObj2.src = $('.image2').attr('src');;
    imageObj2.onload = function() {
      ctx.globalAlpha = 0.5;
      ctx.drawImage(imageObj2, 15, 85, 300, 300);
      var img = canvas.toDataURL('image/jpeg');
      $('.merged-image').attr('src', img);
      $('.merged-image').removeClass('hidden');
    }
  };
}

Additionally, it incorporates a bit of transparency just to allow for two jpegs to be utilized.

Note that all image positioning & sizing is managed via the ctx.drawImage() functions. The demo will be ugly, but it should prove the concept. :)

Hopefully this is helpful!

Related