Just as there is a formula for converting an image to grayscale, is there a formula for increasing the brightness of an image and decreasing it in the same level? I tried adding a value to each of the r, g and b pixels. It does increase the brightness but when I reduce the same value, I don't get my original value back.
var pixels = context.getImageData(...);
//loop over the pixel data and add a value
p[i] = p[i]+100;
p[i+1] = p[i+1]+100;
p[i+2] = p[i+2]+100;
This brightens the image. But when I reduce 100 from every pixel, I don't get my original image back.
I read around the web that there are certain formulas to calculate this properly. Can anyone explain it? And similarly for contrast and gamma?
UPDATE:
Thanks all for the suggestions. I tried this after going through some of the posts below.
For increasing brightness:
var pixels = context.getImageData(...);
//loop over the pixel data and add a value
p[i] = p[i]+100 < 255 ? p[i]+100 : 255;
p[i+1] = p[i+1]+100 < 255 ? p[i+1]+100 : 255;
p[i+2] = p[i+2]+100 < 255 ? p[i+2]+100 : 255;
And for reducing brightness:
var pixels = context.getImageData(...);
//loop over the pixel data and add a value
p[i] = p[i]-100 >= 0 ? p[i]-100 : 0;
p[i+1] = p[i+1]-100 >= 0 ? p[i+1]-100 : 0;
p[i+2] = p[i+2]+100 >= 0 ? p[i+2]-100 : 0;
I can see the increment works fine, but when I decrement it, I still don't get the original image, there's a little difference between the original and brightened image!
What am I doing wrong?
A quick search on google showed:
adjust bitmap image brightness/contrast using c++
Links:
https://web.archive.org/web/20140825114946/http://bobpowell.net/image_contrast.aspx
remeber to look for similar questions before you post one :).
EDIT:
Two more links:
Image Processing Algorithms Part 5: Contrast Adjustment:
http://thecryptmag.com/Online/56/imgproc_5.html
Image Processing Algorithms Part 4: Brightness Adjustment:
http://www.dfstudios.co.uk/articles/image-processing-algorithms-part-4/
EDIT:
You have an error in the second block of code you posted:
var pixels = context.getImageData(...);
//loop over the pixel data and add a value
p[i] = p[i]-100 >= 0 ? p[i]-100 : 0;
p[i+1] = p[i+1]-100 >= 0 ? p[i+1]-100 : 0;
p[i+2] = p[i+2]+100 >= 0 ? p[i+2]-100 : 0; // <- Tha p[i+2]+100 should be a p[i+2]-100 right?
What Johannes Jendersie says is true, your problem is this:
Lest say you have a pixel with this values
R = 100;
G = 210;
B = 20;
And you add 100 to each color, now you have:
R = 200;
G = 255; // It was 310 but you have to clamp it to 255.
B = 120;
Now you subtract those same 100:
R = 100; // same
G = 155; // different!, this have to be 210!!
B = 20; // same
That's why this operation is not reversible. What you can do is always have a copy of the original image, and each time you change the value, you re apply the brightness correction.
So the way to undo your operation of adding 100 is not subtracting a 100 but setting the brightness correction value to 0. This is how many image editing program works, you have a slider and while you are at the slider window changing the value you can always get your original image if you set it to 0, but once you "apply" the correction, it can't be undone, when you re open the slider window the "0" is now the image previously filtered.
So you either keep a backup of the image and a brightnesCorrection value somewhere, and each time the value change, you re-apply the correction on the image, or you just have to accept the fact that you won't be able to restore the image to its former glory xD (at least not with this kind of brightness correction, not sure if there is a better way).
Hope it helps.