Introduction
For one of my projects, I need to show an image preview dialog while adjusting brightness and contrast. Here is a sample of what I have created. It doesn't rely on any other graphics library. No GDI+ needed.
Why do it?
Sometimes refreshing a big image file takes a lot of RAM and processor power. A more efficient way is to take a sample from the complete image and show the effect in a preview dialog.
In my example, I am loading the bitmap from a resource file. However, you can easily load a 100x100 sample from your full image to show your user, the effect of your adjustment. I have seen programs that implement a caret box that let you drag around the full image to take such sample.
It is usually not a good idea to resample/resize the image into a 100x100 bitmap and put it into the preview window. The user won't be able to see clearly the final effect.
How?
Only 2 files in the sample project are important:
- DialogBrightnessContrast.h
- DialogBrightnessContrast.cpp
You should look at the BrightnessAndContrast()
function. It loops through every pixel in the bitmap and changes its RGB value.
for (m_nY = 0; m_nY < m_bmp.bmHeight; m_nY++) {
for (m_nX = 0; m_nX < m_bmp.bmWidth; m_nX++) {
m_crC = m_dcSource.GetPixel(m_nX, m_nY);
m_nC = GetRValue(m_crC) + nStepB;
m_nC = floor((m_nC - GREY) * dStepC) + GREY;
m_nR = (m_nC < 0x00) ? 0x00 : (m_nC > 0xff) ? 0xff : m_nC;
m_nC = GetGValue(m_crC) + nStepB;
m_nC = floor((m_nC - GREY) * dStepC) + GREY;
m_nG = (m_nC < 0x00) ? 0x00 : (m_nC > 0xff) ? 0xff : m_nC;
m_nC = GetBValue(m_crC) + nStepB;
m_nC = floor((m_nC - GREY) * dStepC) + GREY;
m_nB = (m_nC < 0x00) ? 0x00 : (m_nC > 0xff) ? 0xff : m_nC;
m_crC = m_nR + (m_nG << 8) + (m_nB << 16);
m_dcOffScreen.SetPixel(m_nX, m_nY, m_crC);
}
}
To adjust brightness you are increasing all the RGB values of a color. To adjust contrast you are exaggerating the difference of a RGB value from GREY(128, 128, 128).
If you have library that does invert, tint and do other graphic manipulations, you can use them here and modify the preview image.
Final words
This is not the most efficient way to apply filter to your whole image. However it is sufficient for the preview dialog. When you hit OK button, you should pass the brightness and contrast values to your super JPG, GIF, PNG engine to crank out the best optimized photo.
May the code be with you.