Node.js GraphicsMagick / ImageMagick (gm) script to create / process 6 images
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

Using gm package for node.js (https://www.npmjs.org/package/gm), I need to create 6 images of specified resolutions.

The 6 resolutions are:
640x960
640x1136
768x1024
1024x768
1536x2048
2048x1536

I need these 6 images created using 2 different methods.

First - Specific background color (i.e. #333333), and output directory as inputs. Optionally specify another image file location as input.

When no image file input, simply create and save the 6 images in the output directory, with the given background color.

When image file input, I want the specified image to be placed in the middle of each created image, with size 256x256 for the first 4 resolutions, and 512x512 for the last 2 resolutions. The original image should not be modified - you may create a copy of it in the output directory if needed.

Second - Take one image file and output directory as inputs, and create the 6 specified resolutions in the output directory by cropping and scaling the input image appropriately. For the cropping and scaling, please use the full width or height (whichever is not limiting dimension), and crop the other dimension equally on both sides.

For example: to create the 640x960 image out of a 320x320 image, the height is the limiting dimension, so first scale the 320x320 image to 960x960, use the full 960 height, and then crop the middle 640 of the image (cutting off the left and right sides).

Another example: to create the 640x960 image out of a 500x2000 image, the width is the limiting dimension so first scale the 500x2000 image to 640x(640/500)*2000, and then crop the middle 960 (cutting off the top and bottom).

The solution should preferably not use any non-standard libraries, and obviously simplicity of code is a strong requirement.

awarded to AjiTae

Crowdsource coding tasks.

1 Solution

Winning solution

var gm = require('gm');

function first(inputDir, image, resolutions, color, outputDir){
    if(!outputDir) outputDir = inputDir;
    if(!image){
        return resolutions.forEach(function(res){
            gm(res.width, res.height, color)
            .write(outputDir + color + '_' + res.width + 'x' + res.height + '.png', function (err) {
            if (err) console.log(err);
            });
        });
    }

    var img = image.split(/(?=\.[^.]+$)/),
        name = img[0],
        type = img[1];

    resolutions.forEach(function(res){
        gm(inputDir + image)
        .background(color)
        .resize(res.min, res.min, '!')
        .gravity('Center')
        .extent(res.width, res.height)
        .write(outputDir + name + '_' + color + '_' + res.width + 'x' + res.height + type, function (err) {
            if (err) console.log(err);
        });
    })
}

function second(inputDir, image, resolutions, outputDir){
    if(!outputDir) outputDir = inputDir;

    var img = image.split(/(?=\.[^.]+$)/),
        name = img[0],
        type = img[1];

    resolutions.forEach(function(res){
        gm(inputDir + image)
        .resize(res.width, res.height, '^')
        .gravity('Center')
        .crop(res.width, res.height)
        .write(outputDir + name + '_' + res.width + 'x' + res.height + type, function (err) {
            if (err) console.log(err);
        });
    })
}

var res = [
    {
        width: 640,
        height: 960,
        min: 256
    },
    {
        width: 640,
        height: 1136,
        min: 256
    },
    {
        width: 768,
        height: 1024,
        min: 256
    },
    {
        width: 1024,
        height: 768,
        min: 256
    },
    {
        width: 1536,
        height: 2048,
        min: 512
    },
    {
        width: 2048,
        height: 1536,
        min: 512
    }
];


//usage
first('/', 'image.png', res, '#333333');
second('/', 'image.png', res);

first('/', '', res, '#333333');
second('/', 'image.jpg', res, '/path/');
Thank you, looks great.
jcszephyr almost 5 years ago
AjiTae - I am looking for a slight modification, maybe you can help. Posted new bounty to add opacity parameter. Thanks. https://bountify.co/node-js-graphicsmagick-imagemagick-gm-add-opacity-to-existing-script
jcszephyr almost 5 years ago