Reputation: 4408
Once I have loaded a BITMAP from file, with LoadImage:
HBITMAP renderBMP = (HBITMAP)LoadImage( NULL, filePath, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE );
is there a way to easily access and edit the pixels individually?
I can use this to get the bitmap object, but it doesn't seem to help,
BITMAP bm;
GetObject(renderBMP, sizeof(bm), &bm);
because the value of bmBits in the structure is 0.
UPDATE:
Now I am getting a bug with this solution:
struct Pixel { unsigned char r,g,b,a; };
void Frame::PushMemory(HDC hdc)
{
BITMAPINFO bi;
ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
GetDIBits(hdc, renderBMP, 0, bi.bmiHeader.biHeight, NULL, &bi, DIB_RGB_COLORS);
/* Allocate memory for bitmap bits */
Pixel* pixels = new Pixel[bi.bmiHeader.biHeight * bi.bmiHeader.biWidth];
int n = sizeof(Pixel) * bi.bmiHeader.biHeight * bi.bmiHeader.biWidth;
int m = bi.bmiHeader.biSizeImage;
GetDIBits(hdc, renderBMP, 0, bi.bmiHeader.biHeight, pixels, &bi, DIB_RGB_COLORS);
// Recompute the output
//ComputeOutput(pixels);
// Push back to windows
//SetDIBits(hdc, renderBMP, 0, bi.bmiHeader.biHeight, pixels, &bi, DIB_RGB_COLORS );
//delete pixels;
}
I get this error:
Run-Time Check Failure #2 - Stack around the variable 'bi' was corrupted.
The last three lines don't seem to matter whether commented in or not.
Upvotes: 1
Views: 3216
Reputation: 1974
Use GetDIBits to access pixels. It copies all pixels into specified buffer. After pixels' modification you can use SetDIBits to write pixels back to bitmap.
EDIT: Example of code:
LPVOID lpvBits=NULL; // pointer to bitmap bits array
BITMAPINFO bi;
ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
if (!GetDIBits(hDC, hBmp, 0, height, NULL, &bi, DIB_RGB_COLORS))
return NULL;
/* Allocate memory for bitmap bits */
if ((lpvBits = new char[bi.bmiHeader.biSizeImage]) == NULL)
return NULL;
if (!GetDIBits(hDC, hBmp, 0, height, lpvBits, &bi, DIB_RGB_COLORS))
return NULL;
/* do something with bits */
::SetDIBits( hDC, hBmp, 0, height, ( LPVOID )lpvBits, &bi, DIB_RGB_COLORS );
Upvotes: 4
Reputation: 36026
If you pass the LR_CREATEDIBSECTION flag to LoadImage it creates a special kind of bitmap with a usermode memory section containing the bits of the bitmap.
GetObject on a DIBSection bitmap will fill in the bmPits pointer of the BITMAP structure, or even fill in a DIBSECTION struct with extra data.
Upvotes: 0