ok.. using the GetCurrentObject() i can get the HBITMAP and the GetObject() give the BIMAP.
using once the GetDIBits(), without using the pixels array, from that HBITMAP, i can get the BITMAPINFO.
and using the GetDIBits(), we can get the pixels array.
now heres the function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
typedef std::vector<BYTE> PixelArray;
PixelArray GetImagePixel(HDC hdcImage)
{
BITMAP bmp = {0};
BITMAPINFO Info = {0};
memset( &bmp, 0, sizeof(BITMAP) );// clear the BITMAP structure
HBITMAP hBitmap =(HBITMAP) GetCurrentObject(hdcImage, OBJ_BITMAP);//get HBITMAP from HDC
GetObject(hBitmap, sizeof(BITMAP), &bmp); //get the BITMAP from HBITMAP
BITMAPINFO info { };
//yes some info we must add manually:
info.bmiHeader.biSize = sizeof(info.bmiHeader);//some structures need their size for work
info.bmiHeader.biWidth = bmp.bmWidth;
// pay attention to the sign, you most likely want a
// top-down pixel array as it's easier to use
info.bmiHeader.biHeight = -bmp.bmHeight;//don't forget that the image is from top to down, but DIB's is inverted
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biCompression = BI_RGB;
// the following calculations work for 16/24/32 bits bitmaps
// but assume a byte pixel array
size_t pixelSize = info.bmiHeader.biBitCount / 8;
// the + 3 ) & ~3 part is there to ensure that each
// scan line is 4 byte aligned
size_t scanlineSize = (pixelSize * info.bmiHeader.biWidth + 3) & ~3;
size_t bitmapSize = bmp.bmHeight * scanlineSize;
PixelArray pixels(bitmapSize);
GetDIBits(hdcImage, hBitmap, 0, bmp.bmHeight, &pixels[0], &info, DIB_RGB_COLORS);
bmp.bmHeight = std::abs(bmp.bmHeight);
return pixels;
}
| |
and now heres the SetImageData():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
void SetImageData(HDC hdcDestination, PixelArray pixels)
{
BITMAP bmp = {0};
BITMAPINFO Info = {0};
memset( &bmp, 0, sizeof(BITMAP) );
HBITMAP hBitmap =(HBITMAP) GetCurrentObject(hdcDestination, OBJ_BITMAP);
GetObject(hBitmap, sizeof(BITMAP), &bmp);
BITMAPINFO info { };
info.bmiHeader.biSize = sizeof(info.bmiHeader);
info.bmiHeader.biWidth = bmp.bmWidth;
// pay attention to the sign, you most likely want a
// top-down pixel array as it's easier to use
info.bmiHeader.biHeight = -bmp.bmHeight;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biCompression = BI_RGB;
SetDIBits(hdcDestination, hBitmap, 0, bmp.bmHeight, &pixels[0], &info, DIB_RGB_COLORS);
}
| |
note: i'm update the code for get the image size and the bitcount:
1 2 3 4 5 6 7
|
struct PixelsArray
{
int Bitcount = 0;
int ImageWidth = 0;
int ImageHeight = 0;
PixelArray Pixels;
};
| |
because we need calculate:
- the 'pixelSize', with 'bm.bmBitsPixel';
size_t pixelSize = bm.bmBitsPixel / 8;
- the 'scanlineSize' with 'pixelSize' and 'bm.bmWidth'(and more):
size_t scanlineSize = (pixelSize * bm.bmWidth + 3) & ~3;
- and the 'pixelOffset':
size_t pixelOffset = y * scanlineSize + x * pixelSize;
for we getting the pixels positions and the RGB separed:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
//how use it
/*PixelArray pixels=GetImagePixel(imgImage);
size_t pixelSize = bm.bmBitsPixel / 8;
size_t scanlineSize = (pixelSize * bm.bmWidth + 3) & ~3;
int x=0, y=0;
for(y=0; y<imgImage.height(); y++)
{
for(x=0; x<imgImage.width(); x++)
{
size_t pixelOffset = y * scanlineSize + x * pixelSize;
COLORREF clrActualColor=RGB(pixels[pixelOffset+2],pixels[pixelOffset+1],pixels[pixelOffset+ 0]);
if(clrActualColor ==RGB(0,0,0))
{
pixels[pixelOffset+2]=GetRValue(GetSysColor(COLOR_MENU));
pixels[pixelOffset+1]=GetGValue(GetSysColor(COLOR_MENU));
pixels[pixelOffset+0]=GetBValue(GetSysColor(COLOR_MENU));
}
}
}
SetImageData(hMemDC,pixels);*/
| |
but i need ask: the GetImagePixel() use 1 HDC and the SetImageData() use a different HDC\HBITMAP but the same pixel array(i mean from GetImagePixel()):
so the SetDIBits() can't combine the pixel array on the HDC\HBITMAP destination?
did i miss something on SetImageData()?
(i get a black result... well... no result. for now i'm not testing the function returns)
note: these code works fine when i use the same HDC\HBITMAP.