Formula for adjusting brightness / contrast on canvas?

Just as there is a formula for converting an image to shades of gray, is there a formula for increasing the brightness of an image and decreasing it at the same level? I tried adding a value to each of the r, g, and b pixels. This increases the brightness, but when I decrease the same value, I do not get my original value.

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 will improve the image. But when I reduce 100 of each pixel, I do not return my original image.

I read on the net that there are certain formulas to correctly calculate this. Can anyone explain this? And similarly for contrast and gamma?

UPDATE:

Thanks everyone for the suggestions. I tried this by going through some of the posts below.

To increase the 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 to reduce the 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 see that the increment is working fine, but when I decrease it, I still do not get the original image, there is a slight difference between the original and the bright image!

What am I doing wrong?

+4
source share
2 answers

A quick google search showed:

adjust the brightness / contrast of a bitmap using C ++

References:

http://www.kweii.com/site/color_theory/2007_LV/BrightnessCalculation.pdf

http://www.bobpowell.net/image_contrast.htm

remember to look for similar questions before posting one :).

EDIT:

Two more links:

Image Processing Algorithms Part 5: Contrast Correction:

http://thecryptmag.com/Online/56/imgproc_5.html

Image Processing Algorithms Part 4: Brightness Control:

http://www.dfstudios.co.uk/articles/image-processing-algorithms-part-4/

EDIT:

You have an error in the second block of code that 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 ap[i+2]-100 right? 

What Johannes Jendersie means is your problem:

Let's say you have a pixel with these 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 the same 100:

 R = 100; // same G = 155; // different!, this have to be 210!! B = 20; // same 

That is why this operation is not reversible. What you can do is always have a copy of the original image, and every time you change the value, you apply a brightness correction.

Thus, the way to cancel the add operation 100 does not subtract 100, but sets the brightness correction value to 0. This is how the image editing program works, you have a slider, and while you are in the slider window, changing it you can always get the original image. if you set it to 0, but once you apply the fix, it cannot be undone when you open the slider window, now β€œ0” is the image that was previously filtered.

Thus, you either save a backup image, or the value of brightnesCorrection somewhere, and every time the value changes, you re-apply the correction on the image or just have to accept the fact that you cannot restore the image to its former glory xD (at least not with such brightness correction, not sure if there is a better way).

Hope this helps.

+5
source

Many image operations are not reversible due to the fact of rounding and fixing values.

Each of your color channels p[i] probably has a byte type? If so, you can only store values ​​from 0 to 255. If you add 100, for example, 223, you will get 323, which cannot be stored in 1 byte. This should lead to an overflow of up to 67 or pinched to 255 (the largest possible number). Subtracting 100 will not restore 223, but will result in 155.

Instead of adding an offset, you should try to multiply your colors. But this is due to the answer of Angel Castillo. (There you will also have a loss of information, but the results will be more pleasant)


Reaction to update :

What I had in mind was that clamp values ​​(e.g., actual implementation) lead to data loss. As in the example above, a value that is too large becomes 255. Thus, subtracting 100 will again set all the colors to 155, which would be 155 or more in the original. Information on brighter colors (> 155) is lost.

In other cases (changes in contrast and gamma), you will also receive information about losses, since rounding sets the previous different colors to the same value.

The only way to avoid this is to use other formats with more information per channel. For instance. > 16 bits, signed int or floating point. I doubt your canvas has the ability to do this, so you need to keep your own copy of the background (with a higher range of values). Make all the transformations on your copy and just show the image sandwiched on the canvas.

+5
source

All Articles