下面的代码作用是将一个位图不透明的地方透明,但是用C写的,我照着用C#翻译了一下,没成功,哪位高手可以帮忙翻译一下。用C#自己的MakeTanspent方法作的透明效果不好,对于图片的阴影不能处理。
Bitmap* CreateBitmapFromHBITMAP(IN 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 hbitmapBitmap *pBitmap = new Bitmap(bmp.bmWidth, bmp.bmHeight, PixelFormat32bppPARGB);// Access to the Gdiplus::Bitmap's pixel dataBitmapData 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;// 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 ( Ok != pBitmap->UnlockBits(&bitmapData) )
{
delete pBitmap;
}
delete [] piexlsSrc;
return pBitmap;
}
Bitmap* CreateBitmapFromHBITMAP(IN 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 hbitmapBitmap *pBitmap = new Bitmap(bmp.bmWidth, bmp.bmHeight, PixelFormat32bppPARGB);// Access to the Gdiplus::Bitmap's pixel dataBitmapData 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;// 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 ( Ok != pBitmap->UnlockBits(&bitmapData) )
{
delete pBitmap;
}
delete [] piexlsSrc;
return pBitmap;
}
Bitmap nbmp=new Bitmap(96,96,System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
//下面这一句,如果换成Graphics g=CreateGraphics();由窗体创建的Graphics对象,则可以正确地在窗体上显示图像,但是如果用从Image创建,图像阴影边缘就成了黑色的了
Graphics g=Graphics.FromImage(nbmp);
IntPtr hdcDest = g.GetHdc();
IntPtr hdcMem = IntPtr.Zero;
hdcMem = Win32.CreateCompatibleDC(IntPtr.Zero);
Win32.SelectObject(hdcMem, hBitmap);
Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
blend.AlphaFormat = Win32.AC_SRC_ALPHA;
blend.BlendOp = Win32.AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255;
Win32.AlphaBlend(hdcDest, 0, 0, 96, 96, hdcMem, 0,0, 96, 96, blend);
g.ReleaseHdc(hdcDest);
g.Dispose();
Win32.DeleteObject(hdcMem);
return nbmp;
上面代码中,关键点就在第二行,如果把图像直接绘制在窗体上,则没有问题,如果用nbmp返回,再绘制的话,图像边缘部分就成了黑的了。
请大家再帮看看?