Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gdiplus::Bitmap* CreateBitmapFromHBITMAP 这个代码这里是个BUG吗? #518

Open
vbmaxps opened this issue Feb 7, 2025 · 0 comments

Comments

@vbmaxps
Copy link

vbmaxps commented Feb 7, 2025

Gdiplus::Bitmap *CreateBitmapFromHBITMAP(HBITMAP hBitmap)
{
BITMAP bmp = {0};
if (0 == GetObject(hBitmap, sizeof(BITMAP), (LPVOID)&bmp))
{
return FALSE;
}
// Although we can get bitmap data address by bmp.bmBits member of BITMAP
// which is got by GetObject function sometime,
// we can determine the bitmap data in the HBITMAP is arranged bottom-up
// or top-down, so we should always use GetDIBits to get bitmap data.
BYTE *piexlsSrc = NULL;
LONG cbSize = bmp.bmWidthBytes * bmp.bmHeight;
piexlsSrc = new BYTE[cbSize];
BITMAPINFO bmpInfo = {0};
// We should initialize the first six members of BITMAPINFOHEADER structure.
// A bottom-up DIB is specified by setting the height to a positive number,
// while a top-down DIB is specified by setting the height to a negative number.
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = bmp.bmWidth;
bmpInfo.bmiHeader.biHeight = bmp.bmHeight; // 正数,说明数据从下到上,如未负数,则从上到下
bmpInfo.bmiHeader.biPlanes = bmp.bmPlanes;
bmpInfo.bmiHeader.biBitCount = bmp.bmBitsPixel;
bmpInfo.bmiHeader.biCompression = BI_RGB;
HDC hdcScreen = CreateDC(L"DISPLAY", NULL, NULL, NULL);
LONG cbCopied = GetDIBits(hdcScreen, hBitmap, 0, bmp.bmHeight,
piexlsSrc, &bmpInfo, DIB_RGB_COLORS);
DeleteDC(hdcScreen);
if (0 == cbCopied)
{
delete[] piexlsSrc;
return FALSE;
}
// Create an GDI+ Bitmap has the same dimensions with hbitmap
Gdiplus::Bitmap *pBitmap = new Gdiplus::Bitmap(bmp.bmWidth, bmp.bmHeight, PixelFormat32bppPARGB);
// Access to the Gdiplus::Bitmap's pixel data
Gdiplus::BitmapData bitmapData;
Gdiplus::Rect rect(0, 0, bmp.bmWidth, bmp.bmHeight);
if (Gdiplus::Ok != pBitmap->LockBits(&rect, Gdiplus::ImageLockModeRead,
PixelFormat32bppPARGB, &bitmapData))
{
delete (pBitmap);
return NULL;
}
BYTE *pixelsDest = (BYTE *)bitmapData.Scan0;
int nLinesize = bmp.bmWidth * sizeof(UINT);
int nHeight = bmp.bmHeight;
// Copy pixel data from HBITMAP by bottom-up.
for (int y = 0; y < nHeight; y++)
{
// 从下到上复制数据,因为前面设置高度时是正数。
memcpy_s(
(pixelsDest + y * nLinesize),
nLinesize,
(piexlsSrc + (nHeight - y - 1) * nLinesize),
nLinesize);
}
// Copy the data in temporary buffer to pBitmap
if (Gdiplus::Ok != pBitmap->UnlockBits(&bitmapData))
{
delete pBitmap;//这里 删除了 下面还是返回了pBitmap 不应该 pBitmap = nullptr;
}
delete[] piexlsSrc;
return pBitmap;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant