Using GraphicsMagick for Image Manipulation in Node.js
GraphicsMagick is a free and open-source command-line utility for manipulating images. It is a fork of ImageMagick, but it is faster and uses fewer resources.
If you’re planning on using GraphicsMagick within Node.js, there are several wrappers available in npm from which to choose from. However, there are cases (e.g. you don’t want to depend on third-party modules) where you want to run the utility directly.
For those cases, I’ll show you how to launch GraphicsMagick in a new process, using the child_process
Node.js module.
Start by installing GraphicsMagick:
sudo apt install graphicsmagick
Create your custom GraphicsMagick wrapper in a new file named gm.js
:
var GM_PATH = "/usr/bin/gm"; // Path to the GraphicsMagick binary
var TIMEOUT = 60000; // Kill process after N milliseconds
var childProcess = require("child_process");
function spawn(stdin, args, callback) {
var stdout = [];
var stderr = [];
var p = childProcess.spawn(GM_PATH, args);
var timeoutID = setTimeout(function () {
p.kill("SIGKILL");
stderr.push(new Buffer("SIGKILL"));
}, 60000);
p.stdout.on("data", function (data) {
stdout.push(data);
});
p.stderr.on("data", function (data) {
stderr.push(data);
});
p.on("close", function (code) {
clearTimeout(timeoutID);
if (code || stderr.length) {
console.log("code:", code, "stderr", Buffer.concat(stderr).toString());
return callback();
}
callback(Buffer.concat(stdout));
});
p.stdin.write(stdin);
p.stdin.end();
}
// GraphicsMagick 'convert' command
function convert(image, opt, callback) {
opt = opt ? opt : {};
spawn(
image,
[
"convert",
opt.srcFormat ? opt.srcFormat + ":-" : "-",
"-resize",
(opt.width ? opt.width : "") + "x" + (opt.height ? opt.height : ""),
"-quality",
opt.quality ? opt.quality : "100",
opt.format ? opt.format + ":-" : "PNG:-",
],
callback
);
}
module.exports = {
convert: convert,
};
To test your module, copy paste the code below in a file called test.js
:
var request = require("request");
var gm = require("./gm"); // Import your module
var url =
"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Tour_Eiffel_Wikimedia_Commons.jpg/553px-Tour_Eiffel_Wikimedia_Commons.jpg";
var out = "/tmp/test.jpg"; // Output file
request(
{
method: "GET",
url: url,
encoding: null,
},
function (error, response, body) {
if (!error && response.statusCode == 200) {
gm.convert(
body,
{
srcFormat: null,
width: null,
height: 500,
quality: 90,
format: "JPEG",
},
function (image) {
require("fs").writeFile(out, image, function (err) {
console.log(err ? err : "Success!");
});
}
);
}
}
);
The above program will download a large image from the web, resize it to 500px, and save the new image to /tmp/test.jpg
.
Make sure to install the request
module before running test.js
:
npm install request
node test.js
Success!
For more information on GraphicsMagick, you can have a look at the manual here.