My previous solution relied on the .size
function to calculate dimensions for watermark position. I've since adapted the function so it now positions in bottom-right by using gravity
;
gm(_image)
// WATERMARK - PARAM ORDER: [X Pos, Y Pos, width, height]
.draw(['gravity SouthEast image Over 0,0 256,256 "/path/to/watermark.png"'])
// RESIZE DIMENSIONS - PARAM ORDER: [width, height]
.resize(2048, null)
.write("/path/to/resized/output.jpg", function(err, stdout, stderr, command){
if (err){
return cb(err);
}
return cb("done");
});
256 is the desired width and height of my watermark. The comment above the .draw
states the order that these values are in - if using gravity
to set the position, these are offsets and can be negative.
In this example, the watermark will be in the bottom right corner.
First, you need to .draw
the watermark over the image.
Secondly, you need to .resize
according to your desired output dimensions.
Finally, you then .write
(or .stream
) to your output destination.
EDIT - 23:21, Friday 02 December 2016
I've now built a function that lets you resize the among the longest edge, and choose if you want to watermark it - I figure if you're looking for something like this, I greet you "Hello!", people of the future!
function processImgLongEdge(_image, _outputDest, _maxLongEdge, watermark, cb){
var gm = require("gm").subClass({imageMagick: true});
if (watermark == true){
gm(_image).size(function(err, value){
var isLandscape;
if (value.width > value.height){
isLandscape = true;
} else {
isLandscape = false;
}
if (isLandscape == true){
gm(_image)
.draw(['gravity SouthEast image Over 0,0 256,256 "/full/path/to/watermark.png"'])
.resize(_maxLongEdge, null)
.write(_outputDest, function(err, stdout, stderr, command){
if (err){
return cb(err);
}
return cb("done");
});
} else {
gm(_image)
.draw(['gravity SouthEast image Over 0,0 256,256 "/full/path/to/watermark.png"'])
.resize(null, _maxLongEdge)
.write(_outputDest, function(err, stdout, stderr, command){
if (err){
return cb(err);
}
return cb("done");
});
}
});
} else {
gm(_image).size(function(err, value){
var isLandscape;
if (value.width > value.height){
isLandscape = true;
} else {
isLandscape = false;
}
if (isLandscape == true){
gm(_image)
.resize(_maxLongEdge, null)
.write(_outputDest, function(err, stdout, stderr, command){
if (err){
return cb(err);
}
return cb("done");
});
} else {
gm(_image)
.resize(null, _maxLongEdge)
.write(_outputDest, function(err, stdout, stderr, command){
if (err){
return cb(err);
}
return cb("done");
});
}
});
}
};
To use it, just go with this and configure as necessary;
processImgLongEdge(
"/path/to/input/image.jpg", // Path to original image
"/path/to/output/image.jpg", // Path to output image
600, // Max length of longest edge
false, // Should it have a watermark? <true | false>
function(imgResult){
console.log(imgResult); // Will log "done" or error from gm to the console
}
);
The function could probably be adjusted in some ways, but if you're looking for a 'it just works' solution, this is it.
With some tweaking, you could make it resize along the shortest edge if you prefer, but it's not something I require for my project so I won't cover it here.
composite
afterin
. Basically, you must load the original and resize, set the gravity and geometry, load the watermark and then composite and save. – Mark Setchellidentify watermark.png
– Mark Setchellload original... resize... load watermark... gravity southeast... geometry +20+10... composite... save
– Mark Setchell