I'm trying to write a program that takes in a matrix full of 12-bit RAW sensor values (that range from [512-4096]) (512 is the BAYER sensor black level--> i.e. what pure black is defined as) and adjusts the EV of each pixel, excatly like the Adobe Camera Raw (ACR) "exposure" slider. I'm trying to figure out how it is done basically. I've looked up dozens of blogs that explain how EV is calculated and it seems to be:

This link seems to give the formula of: PixelAdjusted = Pixel * 2^EV

This just seems very wrong because an adjustment of 5 EV blows the picture wayyy out of proportion.. and I can't find any other resources online. Wikipedia has an excellent entry on Exposure Value but it doesn't seem to have what I'm looking for either... any help on this?


Here is an example of what I mean:

RAW file in ACR with EV 0: Before

With EV 5: After

  • 2
    Trying to adjust the exposure of an otherwise correctly exposed image by 5EV when processing the raw file will blow highlights or drown shadows beyond reasonable usability. In my old version of Photoshop, the raw importer only allows adjustments of ±4EV but if you try to increase the exposure of an image by the allowed 4EV, you will probably see that most of the image will come out white.
    – jarnbjo
    Jan 19, 2019 at 19:52
  • True, but I have a very dark, long exposure photo. If I put the photo in ACR and bump up the EV to 5, I get a really nicely brightened photo. If I try and do the same in code, I get messy results. I've added screenshots to further explain what I'm trying to acheive. Jan 19, 2019 at 19:54

3 Answers 3


Your entire exercise seems to be built on somewhat of a false premise: That the initial image you see on your screen when opening a raw image file in ACR is a linear representation of the luminance values collected by each sensel of the camera's sensor. This is not the case. This is not even remotely the case.

What you have labeled, "RAW file in ACR with EV 0" in the question could be more properly labeled: Default ACR rendering of raw file after applying demosaicing, gamma curves, white balance, etc. without any change in EV.

Here's what a linear representation of a properly exposed image looks like when, following demosaicing to generate color information from the monochromatic luminance values measured by each of the cameras sensels, it is saved as a TIFF (before converting to JPEG with no additional processing for web display):

enter image description here

Here's a jpeg thumbnail of the same image attached to the raw file in question with basic in-camera processing that includes demosaicing and gamma correction, but not any EV correction:

enter image description here

Raw image files contain enough data to create a near infinite number of interpretations of that data that will fit in an 8-bit jpeg file.¹ Anytime you open a raw file and look at it on your screen, you are not viewing "THE raw file." You are viewing one among countless possible interpretations of the data in the raw file. The raw data itself contains a single (monochrome) brightness value measure by each pixel well. With Bayer masked camera sensors (the vast majority of color digital cameras use Bayer filters) each pixel well has a color filter in front of it that is either red, green, or blue. For a more complete discussion of how we get color information out of the single brightness values measured at each pixel well, please see RAW files store 3 colors per pixel, or only one?

How the image you see on your monitor when you open a raw file will look is determined by how the application you used to open the file chose to interpret the raw data in the file to produce a viewable image. Each application has its own set of default parameters that determine how the raw data is processed. One of the most significant parameters is how the white balance that is used to convert the raw data is selected. Most applications have many different sets of parameters that can be selected by the user, who is then free to alter individual settings within the set of instructions used to initially interpret the data in the raw file.

Another significant processing step is what we call gamma correction. (Please do not confuse this with adjusting gamma on a monitor. These are two entirely different things.) The linear values collected by the camera's sensor are converted to a scale closer to what the human eye perceives. Rather than having a linear line from darkest to brightest, the shape of the response curve is more of an S-shape when charted on a logarithmic, rather than linear, scale.

If you are viewing an image on a screen, you are not looking at a raw file. What you are seeing is one possible interpretation of the raw data collected by a camera sensor. That interpretation may be one of several things:

  • A jpeg produced by the camera using the raw data from the sensor and the camera's settings current at the time the image was captured.
  • A jpeg preview image attached to a raw image file. The jpeg preview is also produced by the camera's internal processor using the camera's settings current at the time the image was captured. It is attached to the raw image file. This preview is normally what one sees when looking at an image on the LCD on the back of the camera when images are recorded as "raw" files. This preview is also what many photo applications will show when you are viewing thumbnails of raw image files on your computer.
  • A fresh interpretation of the raw image data by a raw processing application such as ACR. Depending on your program settings, when you first open a raw image file, you may see either the jpeg preview image or you may see a new conversion of the raw data based on the current settings of the application with which you opened the image file. If you are seeing a fresh interpretation of the raw image data, it is still in a form that has had the same type of processing applied to it that a jpeg image produced with the same settings would have had.

The thing to keep in mind is that there is no single interpretation of a raw image file that is "THE raw image." Raw data must be processed to be viewed as any meaningful image. The settings of the various processing steps will determine how the result looks. There is no single inherently "correct" way to process the raw data. Things such as color temperature and white balance, contrast, white point, black point, gamma, etc. must be applied to the raw data collected by the sensor before it looks anything like what we call a "photograph."

For more detailed discussions about what the data in a raw image file is and is not, please see these other questions here at Photography at Stack Exchange:

RAW files store 3 colors per pixel, or only one?
Why can software correct white balance more accurately for RAW files than it can with JPEGs?
RAW in ACR vs JPG in ACR
While shooting in RAW, do you have to post-process it to make the picture look good?
Why do RAW images look worse than JPEGs in editing programs?
Why does my Lightroom/Photoshop preview change after loading?
Why is Lightroom changing all the settings on my imported RAWs?

¹ Sure, you could take a picture that contains a single pure color within the entire field of view. but most photos contain a wide variation of hues, tints, and brightness levels.


If I'm understanding what you are trying to do correctly, your starting point is fundamentally flawed.

" ... takes in a matrix full of 12-bit RAW sensor values ..."

OK so far.

" ... and adjusts the EV of each pixel, ..."

Each sensor value is not a pixel!

Possibly I'm reading you too literally, but color pixels are derived from multiple surrounding monochromatic sensors. Exactly how that occurs varies by camera and I doubt, but don't know for sure, that the scaling and normalization is linear across the different color elements. Your program would need to duplicate a pixel build the same way to have a hope of also matching EV changes.

There are open source raw editors, so the information needed to construct the pixels should be available.


I finally figured it out! It took a little guesswork, but I found the formula!

Basically, the website I linked to was correct, but the "raw value" they referenced had to be normalized to a [0,1] scale. So basically the formula is as follows:

black_level = 512
bit_depth = 2**12
normalized = max((pixel - black_level),0) / (bit_depth) ## normalize to [0,1]
exposed = normalized * (2**EV)    ## expose by desired EV value

## scale back to normal level:
pixel_new = exposed * bit_depth   


this didn't work when I tried it with a lot of different images. Also, 0 EV doesn't return the same image, which means formula is wrong. Currently looking into how to fix it...

Not the answer you're looking for? Browse other questions tagged or ask your own question.