node.jsimagemagickimage-manipulationgraphicsmagickgm

Resize and compose two or more images using gm in Nodejs


Given two images, say under img (in size of 1024x768) folder (img1.png and img2.png), I need to resize img2 (say 300x300) and put on img1 in x and y (say 100, 200) from top left of img1. The end result should be 1024x768 size image.

Using gm (https://github.com/aheckmann/gm), tried this:

gm('./img/img1.png')
.composite('./img/img2.png')
.geometry('300x300+100+200')
.write('resultGM.png', (err) => {
  if (err) console.log(err);
});

Expectedly (because of chain on whole operation) it produces 300x300 image. Then I tried this:

gm('./img/img1.png')
.composite(
  gm('./img/img2.png')
  .geometry('300x300+100+200')
)
.write('resultGM.png', (err) => {
  if (err) console.log(err);
});

hoping composite function accepts buffer, but no chance, it only accepts file path, and it gives error. After spending 2-3 hours and reading few posts (only could find some discussions here: How to do composite with gm node.js? and here: Combine two gm objects while resizing one of them in graphicsMagick for NodeJS (this one doesn't answer the question in fact), I couldn't find any solution to do this operation in memory using streams or buffer. It's possible to do while writing to a temporary file. Is there any body out there who could find a solution for in memory resize and merge images on the fly?


Solution

  • Using ImageMagick instead of GraphicMagic;

    After a few hours of searching finally i have figured out how to merge two images resizing and re-ordering layer positions (over, under, etc.) using gm.

    Let's have a look this image first:

    enter image description here

    After a few minutes digging up ImageMagick's compose help page, i saw the usage of DstOver positioning.

    http://www.imagemagick.org/Usage/compose/#dstover

    So, i have tried this code below and it worked like a charm!

    imageMagick(background)
        .composite(image)
        .in('-compose', 'Dst_Over')
        .in('-geometry', '253x253+15+15')
        .write(output, function (err) {
        if (err) console.error(err);
            else console.log('Compose OK!');
        });