Introduction
This article shows a fast way to view and change pixel color data (Windows bitmaps) without using the GetPixel
and SetPixel
methods.
Background
I spent a couple of months in trouble not knowing a fast way to edit images with C++ (I was using the Windows API functions GetPixel
and SetPixel
). I lost a couple of clients. I then spent a couple of weeks browsing through forums trying to find answers. But eventually, I got through this by myself and learned this easy pointer arithmetic method.
Using the Code
We use a pointer to bitmap bits: bitmapzor.GetBits();
. Then, we use a pointer offset to get to another line in the bitmap pixel colors array: bitmapzor.GetPitch();
.
The complete code with comments is listed here:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
CImage bitmapzor;
bitmapzor.Load(_T("C:\\1.bmp"));
printf ("Now we use ATL (Api) GetPixel and SetPixel functions to "
"enforce (for example) all green pixels by 30%\n please "
"press any key to start and start counting minutes :)");
getchar();
COLORREF PixColor=0; int R=0,G=0,B=0;
for (int i=0; i<bitmapzor.GetWidth(); i++) for (int j=0; j<bitmapzor.GetHeight(); j++) {
PixColor = bitmapzor.GetPixel(i,j);
R=GetRValue(PixColor); G=GetGValue(PixColor); B=GetBValue(PixColor); G=(int)((float)G*1.3); if (G>255) G=255; PixColor = RGB(R,G,B); bitmapzor.SetPixel(i,j,PixColor);
}
LPCTSTR filename=_T("C:\\GetPixel.bmp");
bitmapzor.Save(filename);
printf ("Done, file is saved to: %s\n Please press "
"any key for another method demo", filename);
getchar();
printf ("Pointer arithmetics demo (without GetPixel and SetPixel functions): \n");
bitmapzor.Destroy(); bitmapzor.Load("C:\\1.bmp");
BYTE* byteptr = (BYTE*)bitmapzor.GetBits();
int pitch = bitmapzor.GetPitch();
for (int i=0; i<bitmapzor.GetWidth();i++)
for (int j=0; j<bitmapzor.GetHeight();j++)
{
R= *(byteptr+pitch*j+3*i);
G= *(byteptr+pitch*j+3*i+1);
B= *(byteptr+pitch*j+3*i+2);
G=(int)((float)G*1.3);
if (G>255) G=255;
*(byteptr+pitch*j+3*i+1)=G;
}
LPCTSTR filename2 = _T("C:\\ptrarithm.bmp"); bitmapzor.Save(filename2);
printf ("Done, file is saved to: %s\n Please press any key to exit program", filename2);
getchar();
bitmapzor.Destroy(); return 0;
}
Points of Interest
A normal bitmap is a WxH pixel table with a header. Each value in the pixel table is a 24 bit integer or 3xCHAR
s. To access these values, we need to know the starting point of the pointer and the offset. Normal bitmaps have a negative offset; e.g., if the pointer to some line of the color table is a byteptr
, then the pointer to the next line is byteptr-3*W
. But sometimes, bitmaps are upside-down oriented and the pointer to the next line is byteptr+3*W
. Anyway, the offset negative or positive is always given by the GetPitch()
method.
History
This is version 1.0.2 of the article.