bravokiloecho
bravokiloecho

Reputation: 1463

Convert image to monochrome and replace black with colour using Canvas and JS

I'm trying to write some JS which will convert an image to grayscale, and convert the blacks to a colour (pink in this case). The effect I want to achieve is illustrated below (left is the original, right is the desired result):

enter image description here

I've tried using CamanJS and I've got something close-ish using a greyscale filter and a solid pink overlay with a blending mode of mulitply. The JS for this looks like:

$(function () {
    var $images = $('.make-pink');
    $images.each(function () {
        createPinkImage( $(this) );
    });
});


function createPinkImage ( $image ) {
    var $canvas = $('<canvas />');
    var canvas = $canvas[0];
    var imgSrc = $image.attr('src');
    var canvasWidth = $image.parent().width();
    var canvasHeight = $image.parent().height();

    var pink = '#d65fb3';

    $canvas
        .attr('width',canvasWidth)
        .attr('height',canvasHeight)
        .appendTo($('#canvas-container'));

    var image = new Image();
    image.src = imgSrc;

    image.onload = function() {

        Caman( canvas, imgSrc, function () {

            this.greyscale();

            this.newLayer(function () {
                this.fillColor(pink);
                this.setBlendingMode('multiply');
                this.opacity(70);
            });
            this.exposure(40)
            this.render();
        });
    }
}

I've tried to implement this in a jsfiddle but it doesn't produce a result. Here's the link anyway: http://jsfiddle.net/303L2xL4/1/

And here's a screenshot of the result:

enter image description here

As you can see, it's not quite there!

Any help would be really great. I'm not committed to using CarmanJS is there's a better solution with another library or even just vanilla JS

Upvotes: 2

Views: 1516

Answers (1)

user1693593
user1693593

Reputation:

This is because black colors will produce black result as black is 0 and as you know anything multiplied with 0 will remain 0 (dark greys will produce close to black values and so forth).

To solve this you will have to add a brightness effect to the gray-scale image before setting its color (and potentially a slight contrast adjustment as well) to force the values up from 0.

You could also push the pixels through a RGB-HSL/HSV conversion, adjust brightness (L/V) and then convert back to RGB. This is in principle the same as a linear brightness but with typically better result/quality in the end.

Upvotes: 4

Related Questions