GDI+提供了Image类,加载多种类型的图片。但对于32位带Alpha通道的位图,Image会忽略Alpha值。
下面介绍如何使用Image实现透明位图。
HBITMAP hbmp = (HBITMAP)::LoadImage(GetModuleHandle(NULL), bmpname.c_str(), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
因为要使用到位图的位信息,所以不要忘记LR_CREATEDIBSECTION。
GDI+的Bitmap类提供了一个构造函数如下:
Gdiplus::Bitmap(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, PixelFormat32bppARGB, bm.bmBits)。
使用该构造函数已经可以实现透明的效果,但位图数据是按从下往上的顺序排列的,也就是说bm.bmBits指向的第一行数据是位图的最后一行,而最后一行数据是位图的第一行。
这个构造函数会将bm.bmBits指向的数据按照自上而下的顺序处理,所以最后生成的Bitmap对象会出现上下颠倒的问题。
所以我们要手动对Bitmap对象进行赋值。代码如下:
使用BITMAP结构体存储图片信息。
BITMAP bm;
GetObject(hbmp, sizeof(bm), &bm);
BYTE* source = (BYTE*)bm.bmBits;
生成一个空的Bitmap对象。
m_image = new Gdiplus::Bitmap(bm.bmWidth, bm.bmHeight, PixelFormat32bppARGB);
得到空Bitmap对象的数据的接口,准备赋值。
Gdiplus::BitmapData datas;
Gdiplus::Rect rc(0, 0, bm.bmWidth, bm.bmHeight);
m_image->LockBits(&rc, Gdiplus::ImageLockMode::ImageLockModeWrite, PixelFormat32bppARGB, &datas);
赋值
byte* dest = (byte*)(datas.Scan0);
for (int y = 0; y < bm.bmHeight; y++)
{
memcpy(dest + (y * bm.bmWidthBytes), source + ((bm.bmHeight - y -1) * bm.bmWidthBytes), bm.bmWidthBytes);
}
赋值完成后,不要忘记关闭接口。
m_image->UnlockBits(&datas);
现在得到的Bitmap对象就可以正常显示透明效果了。