Node.js GraphicsMagick / ImageMagick (gm) Add Opacity to Existing Script
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

Existing Bounty solution here: https://bountify.co/node-js-graphicsmagick-imagemagick-gm-script-to-create-process-6-images

This script has two functions. I'm looking to add an opacity parameter to each function to set an opacity value. For example, if the opacity is 1, then the functions return exactly the same result. If opacity is .5, then it makes the image 50% opaque/transparent, which is equivalent to adding a 50% opacity layer on top.

Thanks,
John

awarded to AjiTae

Crowdsource coding tasks.

1 Solution

Winning solution

var gm = require('gm');

function first(inputDir, image, resolutions, opacity, color, outputDir){
    if(!outputDir) outputDir = inputDir;
    if(!image){
        return resolutions.forEach(function(res){
            gm(res.width, res.height, color + ('0' + Math.round( (1 - opacity) * 255 ).toString(16)).slice(-2))
            .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)
        .operator('Opacity', 'Assign', Math.round( (1 - opacity) * 100 ) + '%')
        .write(outputDir + name + '_' + color + '_' + res.width + 'x' + res.height + type, function (err) {
            if (err) console.log(err);
        });
    })
}

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

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

    resolutions.forEach(function(res){
        gm(inputDir + image)
        .operator('Opacity', 'Assign', Math.round( (1 - opacity) * 100 ) + '%')
        .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
    }
];


first('/', 'image.png', res, .5, '#FF0000')
second('/', 'image.png', res, .1)
Hi AjiTae, This solution is not working for me. I am trying command: first('/', '', res, .5, '#FF0000') And I get just a red image without any opacity change. I am running locally on Mac OS X. Please advise. Thanks, John
jcszephyr almost 5 years ago
If you want to adjust backgroud-color opacity - just add opacity value to the "color" arg: first('/', null, res, 1, '#FF000080'). "Opacity" arg is for image. I can change this behavior if you want it.
AjiTae almost 5 years ago
I can try that. But I also cannot get this working when I do include an image.png. The image gets placed correctly on the specified background color, but the image is in its original form with no opacity difference. Is there a way to simply add a 50% white opacity layer on top of the whole picture, including input image and background color together? That is the effect I am looking for. Thanks, John
jcszephyr almost 5 years ago
I've updated solution, check it please. first('/', 'image.png', res, .5, '#FF0000');
AjiTae almost 5 years ago
Hi AjiTae, It worked for: first('/', null, res, .5, '#FF0000') but not for: first('/', 'image.png', res, .5, '#FF0000') I modified your .background(color) in line 20 to include the opacity suffix, and then it seemed to work on the input image as well. Thanks for your help. Well done! Cheers, John
jcszephyr almost 5 years ago