Bright & Proper

My husband was curious about how to make his photos look brighter with code while I was away so he grabbed a star studded algorithm from someone on github and then came to me after it didn’t work like he thought it would.  

The star studded algorithm (it had at least a billion github stars) was just adding integers to the individual RGB values. In other words, it was doing: r = r + 30; g = g + 30; b = b + 30; 

The reason why adding integers to the individual RGB values does not produce the brightness results that a serious photographer might expect is that each value contains information not only about the brightness of each pixel but also about the saturation and the hue. 

In order to obtain information about only the brightness of a pixel one must convert to a space that has separate channels for hue, saturation, and brightness.

The image in the middle below is the original image that my husband wanted to brighten. The image on the right side is produced using the star studded algorithm from github. The image on the left side of the original is what my husband was expecting to see.

Night and Day

The image on the right side may seem brighter to the untrained eye, but it is also less saturated, and the hue is off.

It is easy to achieve the image on the left from the image on the middle with a proper brightness function, provided below in Javascript.

The rgb2separate_channels() and separate_channels2rgb() functions below could be simply rgb2hsv() and hsv2rgb() used in previous examples in this blog, or they could be something fancier.

/* -------------------------------------------------  
 This content is released under the GNU License  
 Author: Marina Ibrishimova 
 Number of Stars on githubs: 0
 Version: 1.0
 Purpose: Brighten a photo 
 ---------------------------------------------------- */
function proper_brightness(imageData, amount) {  
        var ind, 
        $width = imageData.width,
        $height = imageData.height,
        $x, $y, $r, $g, $b, $hue, $saturation, $brightness;
        for($x = 0; $x < $width; $x++) 
            for($y = 0; $y < $height; $y++) 
                if($y === 0) {ind = $x*4;} 
                else {ind = (($y*$width) + $x) * 4;}
                $r = imageData.data[ind];
                $g = imageData.data[ind+1];
                $b = imageData.data[ind+2];
                 //convert to separate channel
                var separate_channels= rgb2separate_channels()($r, $g, $b);
                $hue = separate_channels[0];
                $saturation = separate_channels[1];
                $brightness = separate_channels[2];
                // amount > 1 brightens and < 0 darkens
                $brightness = $brightness*amount;
                if($brightness>1){$brightness = 1;}
                else if($brightness<0){$brightness = 0;}
                var rgb = separate_channels2rgb($hue, $saturation, $brightness);
                $r = rgb[0];
                $g = rgb[1];
                $b = rgb[2];

                imageData.data[ind] = $r;
                imageData.data[ind+1] = $g;
                imageData.data[ind+2] = $b;