IntroductionThere are many image processing tools similar to what I describe in this article. In this personal tool, I have used very basic image processing algorithms. Here I have focused on brightness, color inversion, contrast, blur, sharpness, and black and white color algorithms. I have used GDI+ for loading the image into memory, with the help of formulas mentioned for each kind of image processing. The code includes the CImageProcess.cpp and CImageProcess.h files. I would like to suggest that for image processing, do not use GetPixel and SetPixel . Performance wise, they are very slow. For more information, check this article: Rotate a Bitmap at Any Angle Without GetPixel/SetPixel. Original Image
Algorithm and Code- Brightness
An image can be light or sark. If we want to have more light in the image, we should decrease the RGB value. If we want an image to be darker, we should increase the RGB value. 
Formula Collapse | Copy CodeColor = Color + Value(may be –ve)
if (Color <0) Color = 0; if (Color>255) Color = 255; For example, if we want to decrease the red color component: Collapse | Copy CodeRed = Red - DecrementVal To increase the red color component: Collapse | Copy CodeRed = Red + IncrementVal The code Collapse | Copy CodeBITMAPINFO bi;
BOOL bRes;
char *buf;
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = m_nWidth;
bi.bmiHeader.biHeight = m_nHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = m_nWidth * 4 * m_nHeight;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
buf = (char *) malloc(m_nWidth * 4 * m_nHeight);
bRes = GetDIBits(hMemDC, m_hBitmap, 0, m_nHeight, buf, &bi,
DIB_RGB_COLORS);
long nCount=0;
for (int i=0; i<m_nHeight; ++i)
{
for (int j=0; j<m_nWidth; ++j)
{
long lVal=0;
memcpy(&lVal, &buf[nCount], 4);
int b = GetRValue(lVal);
int g = GetGValue(lVal);
int r = GetBValue(lVal);
r += nRedVal;
if (r >255)
{
r = 255;
}
if (r <0)
{
r = 0;
}
g += nGreenVal;
if (g>255)
{
g = 255;
}
if (g<0)
{
g = 0;
}
b += nBlueVal;
if (b >255)
{
b = 255;
}
if (b<0)
{
b = 0;
}
lVal = RGB(b, g, r);
memcpy(&buf[nCount], &lVal, 4);
nCount+=4;
}
}
SetDIBits(hMemDC, m_hBitmap, 0, bRes, buf, &bi,
DIB_RGB_COLORS);
free(buf); - Invert Color
When we invert color, we get the opposite colors of the current pixels. 
Formula Collapse | Copy CodeColor = 255 – Color; if (Color <0) Color = 0;
if (Color>255) Color = 255; The code Collapse | Copy Codefor (int i=0; i<m_nHeight; ++i)
{
for (int j=0; j<m_nWidth; ++j)
{
long lVal=0;
memcpy(&lVal, &buf[nCount], 4);
int b = 255-GetRValue(lVal);
int g = 255-GetGValue(lVal);
int r = 255-GetBValue(lVal);
lVal = RGB(b, g, r);
memcpy(&buf[nCount], &lVal, 4);
nCount+=4;
}
} - Contrast Color
Contrasting colors are colors that are opposite on the color wheel. In a high contrast image, you can see definite edges, and the different elements of that image are accented. In a low contrast image, all the colors are nearly the same, and it's hard to make out the details. 
Formula Collapse | Copy CodeColor = (((Color - 128) * ContrastVal) / 100) +128
if (Color <0) Color = 0; if (Color>255) Color = 255; Here, the contrast value is between 0 and 200. The code Collapse | Copy Codefor (int i=0; i<m_nHeight; ++i)
{
for (int j=0; j<m_nWidth; ++j)
{
long lVal=0;
memcpy(&lVal, &buf[nCount], 4);
int b = GetRValue(lVal);
int g = GetGValue(lVal);
int r = GetBValue(lVal);
r = ((r-128)*nContrastVal)/100 +128;
g = ((g-128)*nContrastVal)/100 +128;
b = ((b-128)*nContrastVal)/100 +128;
if (r >255)
{
r = 255;
}
if (r <0)
{
r = 0;
}
if (g>255)
{
g = 255;
}
if (g<0)
{
g = 0;
}
if (b >255)
{
b = 255;
}
if (b<0)
{
b = 0;
}
lVal = RGB((int)b, (int)g, (int)r);
memcpy(&buf[nCount], &lVal, 4);
nCount+=4;
}
} - Blur
Blur is the well-known effect on computer screens, in fact on all pixel devices, where the diagonal and curved lines are displayed as a series of little zigzag horizontal and vertical lines. 
Formula Collapse | Copy CodeColor = (C1+C2+C3+C4+C5)/5 For more details about blur and anti-aliasing check this article: Creating graphics for the Web: Anti-aliasing. Here, C1 is the current pixel. C2, C3, C4, and C5 are the nearby pixels. 
The code Collapse | Copy CodepOriBuf = (char *) malloc(m_nWidth * 4 * m_nHeight);
char *tmpBuf = (char *) malloc(m_nWidth * 4 * m_nHeight);
bRes = GetDIBits(hMemDC, m_hBitmap, 0, m_nHeight, pOriBuf, &bi,
DIB_RGB_COLORS);
long nCount=0;
long c1, c2, c3, c4, c5;
for (int i=0; i<m_nHeight; ++i)
{
for (int j=0; j<m_nWidth; ++j)
{
long lVal=0;
memcpy(&lVal, &pOriBuf[nCount], 4);
int b = GetRValue(lVal);
int g = GetGValue(lVal);
int r = GetBValue(lVal);
c1 = r;
if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) &&
(nCount > (m_nWidth*4)))
{
memcpy(&lVal, &pOriBuf[nCount-(m_nWidth*4l)], 4);
c2 = GetBValue(lVal);
memcpy(&lVal, &pOriBuf[nCount+4], 4);
c3 = GetBValue(lVal);
memcpy(&lVal, &pOriBuf[(nCount+(m_nWidth*4l))], 4);
c4 = GetBValue(lVal);
memcpy(&lVal, &pOriBuf[nCount-4], 4);
c5 = GetBValue(lVal);
r = (c1+c2+c3+c4+c5)/5;
}
c1 = g;
if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) &&
(nCount > (m_nWidth*4)))
{
memcpy(&lVal, &pOriBuf[(nCount-(m_nWidth*4l))], 4);
c2 = GetGValue(lVal);
memcpy(&lVal, &pOriBuf[nCount+4], 4);
c3 = GetGValue(lVal);
memcpy(&lVal, &pOriBuf[(nCount+(m_nWidth*4l))], 4);
c4 = GetGValue(lVal);
memcpy(&lVal, &pOriBuf[nCount-4], 4);
c5 = GetGValue(lVal);
g = (c1+c2+c3+c4+c5)/5;
}
c1 = b;
if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) &&
(nCount > (m_nWidth*4)))
{
memcpy(&lVal, &pOriBuf[(nCount-(m_nWidth*4l))], 4);
c2 = GetRValue(lVal);
memcpy(&lVal, &pOriBuf[nCount+4], 4);
c3 = GetRValue(lVal);
memcpy(&lVal, &pOriBuf[(nCount+(m_nWidth*4l))], 4);
c4 = GetRValue(lVal);
memcpy(&lVal, &pOriBuf[nCount-4], 4);
c5 = GetRValue(lVal);
b = (c1+c2+c3+c4+c5)/5;
}
lVal = RGB(b, g, r);
memcpy(&tmpBuf[nCount], &lVal, 4);
nCount+=4;
}
}
SetDIBits(hMemDC, m_hBitmap, 0, bRes,
tmpBuf, &bi, DIB_RGB_COLORS);
free(pOriBuf);
free(tmpBuf); - Sharpness

Formula Collapse | Copy CodeColor = (C1*5) – (C2+C3+C4+C5).
if (Color <0) Color = 0; if (Color>255) Color = 255; The code Collapse | Copy Codefor (int i=0; i<m_nHeight; ++i)
{
for (int j=0; j<m_nWidth; ++j)
{
long lVal=0;
memcpy(&lVal, &pOriBuf[nCount], 4);
int b = GetRValue(lVal);
int g = GetGValue(lVal);
int r = GetBValue(lVal);
c1 = r;
if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) && (nCount > (m_nWidth*4)))
{
memcpy(&lVal, &pOriBuf[nCount-(m_nWidth*4l)], 4);
c2 = GetBValue(lVal);
memcpy(&lVal, &pOriBuf[nCount+4], 4);
c3 = GetBValue(lVal);
memcpy(&lVal, &pOriBuf[(nCount+(m_nWidth*4l))], 4);
c4 = GetBValue(lVal);
memcpy(&lVal, &pOriBuf[nCount-4], 4);
c5 = GetBValue(lVal);
r = (c1*5) - (c2+c3+c4+c5);
}
c1 = g;
if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) && (nCount > (m_nWidth*4)))
{
memcpy(&lVal, &pOriBuf[(nCount-(m_nWidth*4l))], 4);
c2 = GetGValue(lVal);
memcpy(&lVal, &pOriBuf[nCount+4], 4);
c3 = GetGValue(lVal);
memcpy(&lVal, &pOriBuf[(nCount+(m_nWidth*4l))], 4);
c4 = GetGValue(lVal);
memcpy(&lVal, &pOriBuf[nCount-4], 4);
c5 = GetGValue(lVal);
g = (c1*5) - (c2+c3+c4+c5);
}
c1 = b;
if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) && (nCount > (m_nWidth*4)))
{
memcpy(&lVal, &pOriBuf[(nCount-(m_nWidth*4l))], 4);
c2 = GetRValue(lVal);
memcpy(&lVal, &pOriBuf[nCount+4], 4);
c3 = GetRValue(lVal);
memcpy(&lVal, &pOriBuf[(nCount+(m_nWidth*4l))], 4);
c4 = GetRValue(lVal);
memcpy(&lVal, &pOriBuf[nCount-4], 4);
c5 = GetRValue(lVal);
b = (c1*5) - (c2+c3+c4+c5);
}
if (r >255)
{
r = 255;
}
if (r <0)
{
r = 0;
}
if (g>255)
{
g = 255;
}
if (g<0)
{
g = 0;
}
if (b >255)
{
b = 255;
}
if (b<0)
{
b = 0;
}
lVal = RGB(b, g, r);
memcpy(&tmpBuf[nCount], &lVal, 4);
nCount+=4;
}
} - Black and white color
Black and white images can be arrived at by giving the same color value for Red, Green, and Blue. 
Formula Collapse | Copy CodeColor = (R+G+B)/3; R = Color; G = Color; B = Color; The code Collapse | Copy Codefor (int i=0; i<m_nHeight; ++i)
{
for (int j=0; j<m_nWidth; ++j)
{
long lVal=0;
memcpy(&lVal, &buf[nCount], 4);
int b = GetRValue(lVal);
int g = GetGValue(lVal);
int r = GetBValue(lVal);
lVal = (r+g+b)/3;
lVal = RGB(lVal, lVal, lVal);
memcpy(&buf[nCount], &lVal, 4);
nCount+=4;
}
}
|