关于使用GDI+使用位图的说明

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对象就可以正常显示透明效果了。









©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页