Clms
Clms

Reputation: 733

Convert Grayscale to Pastel

I have many different grays (ranging from black to white) which I want to convert to random pastel colors where each pastel has the same brightness as the gray color did. So a dark gray should be converter to any random dark pastel color.

I found a way to generate random pastel colors (Algorithm to randomly generate an aesthetically-pleasing color palette) but I don't know how to convert a gray to a pastel color with the same brightness.

Does anybody have an idea how to approach this problem?

Thanks a lot!

Upvotes: 0

Views: 343

Answers (1)

M Oehm
M Oehm

Reputation: 29116

You can just do a linear inpterpolation between two colours, a "black" colour that corresponds to a grey value of zero and a "white" colour that corresponds to a grey value of 255.

The effect you describe would use your pastel as "black" and white as "white". Colour interpolations in RGB space are tricky when different hues are involved, but in your case, where the two colours have the same or similar hues, there should be no problem. (Your original code to get a nice pastel colour probably uses the same mechanism by interpolating halfway between white and a random colour.)

Here's an example that turns greyscale image data into a pastel colour scheme based on the red value of the data. (Greys have three identical colour components, but no effort is made to ensure that.)

function pastel(idata, black, white) {
    var data = idata.data;
    var n = 0;

    for (var y = 0; y < idata.height; y++) {
        for (var x = 0; x < idata.width; x++) {
            var grey = data[n] / 255.0;
            var yerg = 1.0 - grey;

            data[n++] = (yerg * black.r + grey * white.r) | 0;
            data[n++] = (yerg * black.g + grey * white.g) | 0;
            data[n++] = (yerg * black.b + grey * white.b) | 0;
            n++;
        }
    }        
}

Edit: Here's a complete webpage for yor copy-and-pasting pleasure. You must have the image file "pic.png" in the same directory. The colours are Javascript objects with r, g and b fields.

The image data comes from a canvas, to which the image is drawn. The image data contains the pixels in rgba format; it can be manipulated and then placed back on the canvas. (The extra n++ in the loop skips the alpha value and leaves it unchanged.)

<!DOCTYPE html>

<html>

<head>
<meta charset="utf-8" />
<title>Colour Interpolation</title>
<script type="text/javascript">

    function pastel(idata, black, white) {
        var data = idata.data;
        var n = 0;

        for (var y = 0; y < idata.height; y++) {
            for (var x = 0; x < idata.width; x++) {
                var grey = data[n] / 255.0;
                var yerg = 1.0 - grey;

                data[n++] = (yerg * black.r + grey * white.r) | 0;
                data[n++] = (yerg * black.g + grey * white.g) | 0;
                data[n++] = (yerg * black.b + grey * white.b) | 0;
                n++;
            }
        }        
    }

    window.onload = function() {
        var cv = document.getElementById("map");
        var cx = cv.getContext("2d");

        var img = document.createElement('img');

        img.src = "pic.png";
        img.onload = function(e) {
            var img = this;
            img.width = img.naturalWidth;
            img.height = img.naturalHeight;

            cv.width = img.width ;
            cv.height = img.height;

            cx.drawImage(img, 0, 0);

            var idata = cx.getImageData(0, 0, img.width, img.height);

            pastel(idata,
                {r: 102, g: 51, b: 0},
                {r: 255, g: 255, b: 204});
            cx.putImageData(idata, 0, 0);
        };

    }

</script>
</head>

<body>
<canvas id="map" width="96" height="96">Kann nix.</canvas>
</body>

</html>

Upvotes: 0

Related Questions