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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.