1.位图数据的保存,BitmapData
使用BitmapData类来保存位图Bitmap的数据,使用方式如下:
Gdiplus::Bitmap bmp(m_nWidth,m_nHeight); //构造位图
Gdiplus::BitmapData data; //定义BitmapData类型的变量
Gdiplus::Rect rc(0,0,bmp.GetWidth(),bmp.GetHeight()); //设置需要锁定的Bitmap图像的区域,为整个图像
bmp.LockBits(&rc,Gdiplus::ImageLockModeRead,bmp.GetPixelFormat(),&data); //锁定位图,设置ImageLockModeRead模式,数据保存为当前位图格式,保存在data中
bmp.UnLockBits(&data); //解锁
(1)关于LockBits()的说明
函数原型
Status LockBits(IN const Rect* rect,
IN UINT flags,
IN PixelFormat format,
OUT BitmapData* lockedBitmapData);
参数Rect*:表示要锁定的位图区域。
参数flags:位图数据的存取方式,包括ImageLockModeRead、ImageLockModeWrite和ImageLockModeUserInputBuf三种方式(枚举类型)。
参数format:表示位图书数据以什么格式保存,默认为PixelFormat32bppARGB。
参数BitmapData:BitmapData对象,保存位图的数据
*注意: LockBits()和UnLockBits()是成对的函数,锁定之后必须解锁,否则位图数据无法使用。
(2)关于BitmapData的说明
class BitmapData
{
public:
UINT Width; //位图像素宽度
UINT Height; //位图像素高度
INT Stride; //每行像素数据的字节数
PixelFormat PixelFormat; //图片格式,默认为PixelFormat32bppARGB
VOID* Scan0; //图片数据指针,使用时转为(BYTE*)类型,即(unsigned char*)类型
UINT_PTR Reserved;
};
位图像素数组布局如下图所示:
Stride*Height 为位图数据的总字节数。
此时,位图Bitmap数据已经保存在了BitmapData中了。
2.Bitmap的拷贝
了解了BitmapData和LockBits()函数 后,就可实现位图数据的拷贝了。通过以上步骤得到位图数据,保存在BitmapData中,然后通过一下方法构造一个新的Bitmap,实现Bitmap的拷贝。
使用BitmapData数据构造Bitmap:
Bitmap newBmp(data.Width, //构造的位图像素宽需要与原图保持一致
data.Height, //像素高
data.Stride, //每行字节数
data.PixelFormat, //图片格式,默认为此格式:PixelFormat32bppARGB
(BYTE*)data.Scan0); //位图数据指针,(BYTE*)类型为(unsigned char*)类型
3.QPixmap 与 Bitmap 的转换,与QImage的相互转换
QPixmap pix;
QImage img = pix.toImage(); //使用QPixmap对象转换为QImage
// QPixmap pix = QPixmap::fromImage(img) //使用QImage对象构造QPixmap
img.convertToFormat(QImage::Format_ARGB32); //转换图片格式,与Bitmap对应
Bitmap newfBmp(img.width(), //对应BitmapData的Width属性
img.height(), //对应BitmapData的Height属性
img.bytesPerLine(), //对应BitmapData的Stride
img.format(), //QImage::Format_ARGB32d对应PixelFormat32bppARGB
img.bits()); //对应BitmapData的Scan0
PixelFormat32bppARGB 说明
#define PixelFormatGDI 0x00020000 // Is a GDI-supported format
#define PixelFormatAlpha 0x00040000 // Has an alpha component
#define PixelFormatCanonical 0x00200000
#define PixelFormat32bppARGB (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical)
即,其值为(10 | (32<<8) | 0x00040000 | 0x00020000 | 0x00200000)。