14

I am wondering if there is a way to combine multiple images into a single image using only JavaScript. Is this something that Canvas will be able to do. The effect can be done with positing, but can you combine them into a single image for download?

Update Oct 1, 2008:

Thanks for the advice, I was helping someone work on a js/css only site, with jQuery and they were looking to have some MacOS dock-like image effects with multiple images that overlay each other. The solution we came up with was just absolute positioning, and using the effect on a parent <div> relatively positioned. It would have been much easier to combine the images and create the effect on that single image.

It then got me thinking about online image editors like Picnik and wondering if there could be a browser based image editor with photoshop capabilities written only in javascript. I guess that is not a possibility, maybe in the future?

Steve T
  • 7,729
  • 6
  • 45
  • 65

3 Answers3

20

I know this is an old question and the OP found a workaround solution, but this will work if the images and canvas are already part of the HTML page.

<img id="img1" src="imgfile1.png">
<img id="img2" src="imgfile2.png">
<canvas id="canvas"></canvas>

<script type="text/javascript">
var img1 = document.getElementById('img1');
var img2 = document.getElementById('img2');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

canvas.width = img1.width;
canvas.height = img1.height;

context.globalAlpha = 1.0;
context.drawImage(img1, 0, 0);
context.globalAlpha = 0.5; //Remove if pngs have alpha
context.drawImage(img2, 0, 0);
</script>

Or, if you want to load the images on the fly:

<canvas id="canvas"></canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img1 = new Image();
var img2 = new Image();

img1.onload = function() {
    canvas.width = img1.width;
    canvas.height = img1.height;
    img2.src = 'imgfile2.png';
};
img2.onload = function() {
    context.globalAlpha = 1.0;
    context.drawImage(img1, 0, 0);
    context.globalAlpha = 0.5; //Remove if pngs have alpha
    context.drawImage(img2, 0, 0);
};        

img1.src = 'imgfile1.png';
</script>
HanaTam
  • 45
  • 10
mikeslattery
  • 4,039
  • 1
  • 19
  • 14
5

MarvinJ provides the method combineByAlpha() in which combines multiple images using its alpha channel. Therefore, you just need to have your images in a format that supports transparency, like PNG, and use that method, as follow:

Marvin.combineByAlpha(image, imageOver, imageOutput, x, y);

image1:

enter image description here

image2:

enter image description here

image3:

enter image description here

Result:

enter image description here

Runnable Example:

var canvas = document.getElementById("canvas");
image1 = new MarvinImage();
image1.load("https://i.imgur.com/ChdMiH7.jpg", imageLoaded);
image2 = new MarvinImage();
image2.load("https://i.imgur.com/h3HBUBt.png", imageLoaded);
image3 = new MarvinImage();
image3.load("https://i.imgur.com/UoISVdT.png", imageLoaded);

var loaded=0;

function imageLoaded(){
  if(++loaded == 3){
    var image = new MarvinImage(image1.getWidth(), image1.getHeight());
    Marvin.combineByAlpha(image1, image2, image, 0, 0);
    Marvin.combineByAlpha(image, image3, image, 190, 120);
    image.draw(canvas);
  }
}
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<canvas id="canvas" width="450" height="297"></canvas>
Gabriel Archanjo
  • 4,547
  • 2
  • 34
  • 41
1

I don't think you can or would want to do this with client side javascript ("combing them into a single image for download"), because it's running on the client: even if you could combine them into a single image file on the client, at that point you've already downloaded all of the individual images, so the merge is pointless.

Daniel Papasian
  • 16,145
  • 6
  • 29
  • 32
  • I was looking for the same solution, just like to say it make sense when it comes huge quantity of items and each of them has more than one custom options, for example the t-shirt(colors), or digital posters(background color). That save a lot of time on listing items. – bard Mar 22 '16 at 16:45
  • its js but when its part of a node js project, it must not run on clients side... – Dwza Jan 08 '21 at 14:34
  • This answer is from 2008, before nodejs existed. Clearly there are reasons one may wish to do this today. I suppose I should just delete the answer now that the world has changed. – Daniel Papasian May 13 '21 at 02:15