javascriptnode.jsimagemagickimagemagick-convertgm

How to nest imagemagick commands in node.js gm library?


Using Imagemagick in node.js through the gm library (https://github.com/aheckmann/gm):

var gm = require('gm').subClass({ imageMagick: true });

I am able to flatten pictures, like this:

convert img1.png img2.png img3.png -flatten out.png

with this js code:

gm().command("convert").in("img1.png").in("img2.png").in("img3.png").in("-flatten").toBuffer('PNG' ...

but now I want to tint one of the images, like this:

convert img1.png \( img2.png -fill green -colorize 50% \) img3.png -flatten out.png

but I had not succeed, I tried:

.in("(img2.png -fill green -colorize 50% )")
.in("\(img2.png -fill green -colorize 50% \)")

what is the proper way to pass nested commands?


Solution

  • I really was not able to solve the issue with gm, as far as understood checking the doc and source code, it is not possible in a single step with the current status of the library. then I found the Jimp library: it is pure javascript and even less featured, it was quite straightforward to implement the desired behavior. work well with node.js in AWS Lambda. applying tint in one buffer and then mixing all together looks like this:

    //each skin_buffer[attr] is a Jimp object build like this: 
         Jimp.read(data.Body, function (err, image) {
            skin[type] = image; 
            cb(err);
          });
    
    //this is how the tint effect is applied in Jimp:
      skin_buffers.hair.color([
        { apply: 'mix', params: [ '#00D', 50 ] }
      ]);
    //.. and this is the composite step. skin is just another jimp object 
      skin.composite(skin_buffers.hair, 0, 0);
      skin.composite(skin_buffers.legs, 0, 0);
      skin.composite(skin_buffers.shoes, 0, 0); 
      skin.composite(skin_buffers.torso, 0, 0); 
      skin.composite(skin_buffers.edges, 0, 0); 
      skin.composite(skin_buffers.face, 0, 0); 
      skin.getBuffer( Jimp.MIME_PNG, function(err, buffer){
        cb(err, buffer);
      });
    

    note: jimp.mix is too slow! for a single 1024x1024 image took 13 seconds!:

    [skins_create]got all the assets!
    TIMER: got assets from s3: 3.193 sg
    [skins_create]["skin","face","hair","torso","legs","shoes","edges"]
     - SUBTIMER : jimp.mix: 13.002
     - SUBTIMER : jimp.composite hair: 0.14
     - SUBTIMER : jimp.composite legs: 0.145
     - SUBTIMER : jimp.composite shoes: 0.15
     - SUBTIMER : jimp.composite torso: 0.147
     - SUBTIMER : jimp.composite face: 0.146
     - SUBTIMER : jimp.get buffer: 0.45
    TIMER: processed buffers: 14.185 sg
    TIMER: stored in s3: 4.21 sg