FromHBITMAP 这个函数会丢失透明信息。
在用 FromHBITMAP 你会发现出来的图是带有黑边的,这是因为这个函数有个 bug,解决的办法是用下列的函数进行转换,大体意思就是自己 memcpy 不要用 FromHBITMAP 函数。
Bitmap* CreateBitmapFromHBITMAP(IN HBITMAP hBitmap) { BITMAP bmp = { 0 }; if ( 0 == GetObject(hBitmap, sizeof(BITMAP), (LPVOID)&bmp) ) { return FALSE; } BYTE *piexlsSrc = NULL; LONG cbSize = bmp.bmWidthBytes * bmp.bmHeight; piexlsSrc = new BYTE[cbSize]; BITMAPINFO bmpInfo = { 0 }; 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; } Bitmap *pBitmap = new Bitmap(bmp.bmWidth, bmp.bmHeight, PixelFormat32bppPARGB); BitmapData bitmapData; Rect rect(0, 0, bmp.bmWidth, bmp.bmHeight); if ( Ok != pBitmap->LockBits(&rect, ImageLockModeRead, PixelFormat32bppPARGB, &bitmapData) ) { SAFE_DELETE(pBitmap); return NULL; } BYTE *pixelsDest = (BYTE*)bitmapData.Scan0; int nLinesize = bmp.bmWidth * sizeof(UINT); int nHeight = bmp.bmHeight; for ( int y = 0; y < nHeight; y++ ) { memcpy_s( (pixelsDest + y * nLinesize), nLinesize, (piexlsSrc + (nHeight - y - 1) * nLinesize), nLinesize); } if ( Ok != pBitmap->UnlockBits(&bitmapData) ) { delete pBitmap; } delete [] piexlsSrc; return pBitmap; }
参考信息:http://blog.sina.com.cn/s/blog_5f8817250100g1dj.html
https://groups.google.com/forum/#!topic/microsoft.public.win32.programmer.gdi/stjG06_EPfM