HTML5 Canvas image contrast

Schahriar SaffarShargh picture Schahriar SaffarShargh · May 9, 2012 · Viewed 22.4k times · Source

I've been writing an image processing program which applies effects through HTML5 canvas pixel processing. I've achieved Thresholding, Vintaging, and ColorGradient pixel manipulations but unbelievably I cannot change the contrast of the image! I've tried multiple solutions but I always get too much brightness in the picture and less of a contrast effect and I'm not planning to use any Javascript libraries since I'm trying to achieve these effects natively.

The basic pixel manipulation code:

var data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
 //Note: data[i], data[i+1], data[i+2] represent RGB respectively
data[i] = data[i];
data[i+1] = data[i+1];
data[i+2] = data[i+2];
}

Pixel manipulation example

Values are in RGB mode which means data[i] is the Red color. So if data[i] = data[i] * 2; the brightness will be increased to twice for the Red channel of that pixel. Example:

var data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
 //Note: data[i], data[i+1], data[i+2] represent RGB respectively
 //Increases brightness of RGB channel by 2
data[i] = data[i]*2;
data[i+1] = data[i+1]*2;
data[i+2] = data[i+2]*2;
}

*Note: I'm not asking you guys to complete the code! That would just be a favor! I'm asking for an algorithm (even Pseudo code) that shows how Contrast in pixel manipulation is possible! I would be glad if someone can provide a good algorithm for Image Contrast in HTML5 canvas.

Answer

Brian picture Brian · Aug 28, 2013

After trying the answer by Schahriar SaffarShargh, it wasn't behaving like contrast should behave. I finally came across this algorithm, and it works like a charm!

For additional information about the algorithm, read this article and it's comments section.

function contrastImage(imageData, contrast) {

    var data = imageData.data;
    var factor = (259 * (contrast + 255)) / (255 * (259 - contrast));

    for(var i=0;i<data.length;i+=4)
    {
        data[i] = factor * (data[i] - 128) + 128;
        data[i+1] = factor * (data[i+1] - 128) + 128;
        data[i+2] = factor * (data[i+2] - 128) + 128;
    }
    return imageData;
}

Usage:

var newImageData = contrastImage(imageData, 30);

Hopefully this will be a time-saver for someone. Cheers!