56

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?

4 Answers 4

75

You can use JavaScript to 'merge' them into one canvas, and convert that canvas to image.

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var imageObj1 = new Image();
var imageObj2 = new Image();
imageObj1.src = "1.png"
imageObj1.onload = function() {
   ctx.drawImage(imageObj1, 0, 0, 328, 526);
   imageObj2.src = "2.png";
   imageObj2.onload = function() {
      ctx.drawImage(imageObj2, 15, 85, 300, 300);
      var img = c.toDataURL("image/png");
      document.write('<img src="' + img + '" width="328" height="526"/>');
   }
};

Due to security, your two images must be on the same domain with your JavaScript file (i.e http://123.com/1.png, http://123.com/2.png and http://123.com/script.js) otherwise the function toDataURL() will raise an error.

Sign up to request clarification or add additional context in comments.

1 Comment

example on codepen
29

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

6 Comments

is there a version of pure js without using node.js?
@lovechillcool you can use the merge-images package in the browser as well. If you don't have npm available, you can include it via a script tag: <script src="https://unpkg.com/merge-images"></script> - Node.js is not a requirement here.
I tried already. But kept getting errors of CORS
I wish i could pass base64 image into the sources array .....My webcam functionality would be much better, i guess.
@kano Great library, this is what I am looking for, May I know how to save the merged image into a folder? there is no documentation on saving images.
|
11

Huỳnh Quốc Phong is partially right:

You can use Canvas to merge images. But they can origin from other domains. Just load the pictures in your dom . Once the pictures are loaded (can be checked with javascript, see below) you can use them in your canvas.

var canvas = canvasBuild.getContext('canvasObj');
var img = document.getElementById('mergePic1');
canvas.drawImage(img, 0, 0);

To check if the images were loaded, I would recommend using the jQuery plugin http://desandro.github.io/imagesloaded/ - but it can also be done without.

Comments

7

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!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.