//To use this, in another file call //require("./gm-composite.js")(gm.prototype); //You can then do gm("baseImage.png").composite(gm("watermark.png"), "SouthEast", function(err, composite_gm_obj){...}); var gm = require('gm'); var randInt = function(min, max) { return Math.floor(min + (Math.random() * (max-min))); }; var randString = function(len) { len = len || 16; var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; var ret = ""; while(ret.length < len) { ret += chars[randInt(0, chars.length)]; } return ret; }; module.exports = function(proto) { proto.compose = function(other, gravity, callback) { // We have potentially two streams to deal with, so we first write the watermark to a file, // then pull the base image from stdin and write to stdout // gm composite -resize 400x400 -gravity center Watermark.png test_image.png test_output.png var path = "/tmp/watermark_"+randString(); var prev = { _subCommand: this._subCommand, _out: this._out.slice(), //copy _in: this._in.slice() }; var curr = this; other.write(path, function(err) { curr.subCommand("composite"); curr.gravity(gravity); curr.in(path); var composite = gm(curr.stream()); //re-applying other properties composite._subCommand = prev._subCommand; composite._out = prev._out; composite._in = prev._in; callback(null, composite); }); return this; }; };