
04-05-2009
|
 | Member | | Join Date: May 2008
Posts: 248
| |
| Re: Break down an image into 8 x 8 blocks
There are several types of BMP images (I suppose that is the Windows BMP format). There may be black and white, or with a palette of colors, or 4 bytes per pixel, which has become the most common today.
As my day of goodness, here is the code tested and approved permits to load a BMP image in memory and get the color of each pixel and much faster than the API GetPixel () which also works: Code: #include <windows.h>
BITMAP bmp1;
HBITMAP hbmp1;
BYTE *DIBits;
HGLOBAL hDIBits;
UINT picture_width, picture_height;
/* ============================================================== */
int init_bitmap(void)
{
hbmp1 = NULL;
hDIBits = NULL;
DIBits = NULL;
picture_width = 0;
picture_height = 0;
return TRUE;
}
/* ============================================================== */
int release_bitmaps(void)
{
if (hbmp1 != NULL) {
DeleteObject(hbmp1);
hbmp1 = NULL;
}
if (hDIBits != NULL) {
GlobalUnlock(hDIBits);
GlobalFree(hDIBits);
hDIBits = NULL;
DIBits = NULL;
}
return TRUE;
}
/* ==============================================================
Load a BMP file into a DIB bitmap.
============================================================== */
static int loadDIBfromBMPfile(HWND hwnd, char *bmp_filename)
{
BITMAPINFO bi;
UINT width, height, components_nb;
HDC hdc;
HDC hdcmem; HBITMAP hbmpmem;
int DIB_x0, DIB_y0, DIB_w;
HBITMAP h_tmp_bmp;
BITMAP tmp_bm;
if (hwnd == NULL)
return -99;
if (hbmp1 != NULL) {
release_bitmaps();
init_bitmap();
}
DIB_x0 = 0; DIB_y0 = 0; DIB_w = 0;
memset(&bi, 0, sizeof(BITMAPINFO));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32; // 32 bit so no padding of the horizontal lines is required
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
// Load file
h_tmp_bmp = (HBITMAP)LoadImage(NULL, bmp_filename, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE);
// LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
GetObject(h_tmp_bmp, sizeof(BITMAP), &tmp_bm);
// N.B.: The GetObject function returns only the width, height, and color format information of the bitmap
DIB_w = DIB_x0 + tmp_bm.bmWidth;
height = DIB_y0 + tmp_bm.bmHeight;
bi.bmiHeader.biWidth = DIB_w;
bi.bmiHeader.biHeight = -height;
bi.bmiHeader.biSizeImage = DIB_w * 4 * height * sizeof(BYTE);
picture_width = DIB_w;
picture_height = height;
// Allocate a buffer for the pixels
hDIBits = GlobalAlloc(GHND, bi.bmiHeader.biSizeImage);
if (hDIBits == NULL)
return(-3);
DIBits = (BYTE *)GlobalLock(hDIBits);
memset(DIBits, 255, bi.bmiHeader.biSizeImage); // Initiailize with white pixels
// Create a memory DC, with a bitmap
hdc = GetDC(hwnd);
if (!hdc) {
GlobalUnlock(hDIBits); GlobalFree(hDIBits);
hDIBits = NULL; DIBits = NULL;
return -5;
}
GetDIBits(hdc, h_tmp_bmp, 0, tmp_bm.bmHeight, DIBits, &bi, DIB_RGB_COLORS);
hbmp1 = CreateDIBitmap(hdc, &bi.bmiHeader, CBM_INIT,
DIBits, &bi, DIB_RGB_COLORS);
DeleteObject(h_tmp_bmp);
ReleaseDC(hwnd, hdc);
if (hbmp1 == NULL) {
MessageBox(hwnd, "Image too big and/or not enough video ram.",
"Error", MB_OK|MB_ICONERROR);
return FALSE;
}
InvalidateRect(hwnd, NULL, TRUE); // Refresh screen
return(0);
}
/* ================================================
Get the color of pixel at x, y
================================================ */
int get_pixel_color(int x, int y, int &blue, int &green, int &red)
{
long int k;
k = (y * picture_width + x) * 4;
*blue = DIBits[k];
*green = DIBits[k + 1];
*red = DIBits[k + 2];
// The fourth integer is not used or is the alpha value
return TRUE;
} |