当前位置: 代码迷 >> VC/MFC >> 浅谈MFC中BitBlt与StretchDIBits的差别
  详细解决方案

浅谈MFC中BitBlt与StretchDIBits的差别

热度:288   发布时间:2016-05-02 03:55:22.0
浅谈MFC中BitBlt与StretchDIBits的区别

一、基础知识

1.BitBlt
BitBlt 用于从原设备中复制位图到目标设备,语法格式如下:
BOOL BitBlt(
HDC hdcDest, // handle to destination DC
int nXDest, // 目标矩形区域的左上角x轴坐标点。
int nYDest, // 目标矩形区域的左上角y轴坐标点。
int nWidth, // 在目标设备中绘制位图的宽度。
int nHeight, // 在目标设备中绘制位图的高度。
HDC hdcSrc, // 源设备上下文对象指针。
int nXSrc, // 源设备上下文的起点x轴坐标,函数从该起点复制位图到目标设备。
int nYSrc, // 源设备上下文的起点y轴坐标,函数从该起点复制位图到目标设备。
DWORD dwRop // 光栅操作代码
);
dwRop有如下选择:
BLACKNESS 使用黑色填充目标区域
DSTINVERT 目标矩阵区域颜色取反
MERGECOPY 使用与运算组合原设备矩形区域的颜色和目标设备的画刷
MERGEPAINT 使用或运算将反向的源矩形区域的颜色和目标矩形区域的颜色合并
NOTSRCCOPY 复制源设备区域的反色到目标设备中
NOTSRCERASE 使用或运算组合源设备区域与目标设备区域的颜色,然后对结果颜色取反
PATCOPY 复制源设备当前选中的画刷到目标设备
PATINVERT 使用异或运算组合目标设备选中的画刷和目标设备区域的颜色
PATPAINT 通过或运算组合目标区域当前选中的画刷和源设备区域反转的颜色
SRCAND 使用与运算组合源设备和目标设备区域的颜色
SRCCOPY 直接复制源设备区域到目标设备中
SRCERASE 使用与运算组合目标设备区域的反色与源设备区域的颜色
SRCINVERT 使用异或运算组合源设备区域颜色和目标设备区域颜色
SRCPAINT 使用或运算组合源设备区域颜色和目标设备区域颜色
WHITENESS 使用白色填充目标区域

2.StretchDIBits
int StretchDIBits(
HDC hdc, // handle to DC
int XDest, // 指定目标矩形左上角的X轴坐标,按逻辑单位表示坐标。
int YDest, // 指定目标矩形左上角的Y轴坐标,按逻辑单位表示坐标。
int nDestWidth, // 指定目标矩形的宽度,按逻辑单位表示宽度。
int nDestHeight, // 指定目标矩形的高度,按逻辑单位表示高度。
int XSrc, // 指向源矩形区域左上角的X轴坐标,按逻辑单位表示坐标。
int YSrc, // 指向源矩形区域左上角的Y轴坐标,按逻辑单位表示坐标。
int nSrcWidth, // 指定源矩形的宽度,按逻辑单位表示宽度。
int nSrcHeight, // 指向源矩形区域左上角的Y轴坐标,按逻辑单位表示坐标。
CONST VOID *lpBits, // 指向DIB位的指针,这些位的值按字节类型数组存储
CONST BITMAPINFO *lpBitsInfo, // 指向BITMAPINFO结构的指针,该结构包含有关DIB方面的信息。
UINT iUsage, // 表示是否提供了BITMAPINFO结构中的成员bmiColors,如果提供了,那么该bmiColors是否包含了明确的RGB值或索引。
DWORD dwRop // 光栅操作代码
);
BITMAPINFO结构具有如下形式:
typedef struct tagBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
其中bmiHeader.biHeight表示图像的高度,但是它可以负值,例如:如果图像大小为512*512,那么
bmiHeader.biHeight = 512 则图像原点在左下角;
bmiHeader.biHeight = -512 则图像原点在左上角;
由于通常图像处理中使用的坐标系坐标原点在图像左上角,所以,通常要将bmiHeader.biHeight设置为负值,使用时较为方便。
(此描述引用来自博客http://blog.csdn.net/bflong/article/details/47298997)

3.区别
StretchBlt是拉伸图像拷贝。参数中比bitblt多。这个是映射模式,从源dc的nXOriginSrc,nYOrignSrc映射到目标dc的nXOriginDest, nYOriginDest。源dc的范围和目标dc的范围执行拉伸隐射。可以看成一个空间几何的四棱椎台体。从一个截面映射到另外一个截面。如果2个截面面积相等,那就是1对1的数据拷贝,如果不是,就按照比例计算拟合数据。

这个需要 SetStretchBltMode 设置拉伸拷贝的数据复合模式。也就是数据拟合的计算方法。

相同的参数 DWORD dwRop 表示光栅计算模式,从源数据-》目标数据的复合,比如拷贝、按位与或等二进制运算。

简单说,bitblt直接按你指定的大小输出源dc到目标dc,而strechblt会调整你源dc大小,使之适应你所指定的目标dc大小,再输出。

也就是说,strechblt输出的图总是完整的,而且充满你指定的目标DC区域,而bitblt则可能输出的图是不完整的,也可能无法充满目标dc制定区域。

4.其他
CImage类是ATL和MFC共用的一个类,其头文件为atlimage.h,主要用于图片文件的打开,显示与保存。
CImage::Create
创建以CImage位图并将它附加到以前构造的CImage对象。
Bool Create(int nWidth, int nHeight, int nBPP, DWORD dwFlags = 0);
参数:
nWidth:CImage 位图的宽度,以像素为单位。
nHeight:CImage 位图的高度,均以像素。 如果 nHeight 为正数的,位图是一个从下到上DIB,并且原点是左下角。 如果 nHeight 为负,位图是一组DIB,并且原点为左上角。
nBPP:位的数目每在位图的像素。 通常4,8,16,24或32。 可以是1单色位图或掩码。
dwFlags:指定位图对象是否具有一个alpha通道。
CImage::Save
用于将图像保存到指定的流或文件在磁盘上。
HRESULT Save(IStream* pStream, REFGUID guidFileType ) const throw();
HRESULT Save( LPCTSTR pszFileName, REFGUID guidFileType= GUID_NULL) const throw();
参数:
pStream
对包含文件图像数据的IStream COM对象的指针。
pszFileName
对文件名的指针的图像。
guidFileType
保存图像的文件类型。 可以是如下内容之一:
ImageFormatBMP 一个未压缩的位图图像。
ImageFormatPNG 可移植网络映像(PNG)压缩图像。
ImageFormatJPEG JPEG压缩图像。
ImageFormatGIF GIF压缩图像。
CImage::ReleaseDC
释放设备上下文。

二、函数应用

设备中的需求功能包括截取图像;在图像上进行绘图操作,并截取带绘图的图像等功能。
简单的截取图像就可以使用函数BitBlt完成,并保存到本地。
对于需要截取带绘图的图像时,可以使用StretchDIBits函数进行操作,设置PBITMAPINFO结构体参数等。
CImage *pImage = new CImage;//创建一个CImage对象的指针
pImage->Create(512, 512, 32, 0);//创建以CImage位图并将它附加到以前构造的CImage对象。
CDC* m_pMemDC;//Windows使用与设备无关的图形设备环境(DC :Device Context) 进行显示 。MFC基 础类库定义了设备环境对象类—-CDC类。
BYTE* m_pImg;
if()
{
BitBlt(pImage->GetDC(), 0, 0, 512,512, m_pMemDC->m_hDC, 0, 0, SRCCOPY);
}
else
{
StretchDIBits(pImage->GetDC(), 0, 0, 512, 512, 0, 0, 512, 512, m_pImg, (PBITMAPINFO)&m_cImgBmpInfo, DIB_RGB_COLORS, SRCCOPY);
}
pImage->Save(strFolderPath);//用于将图像保存到指定的流或文件在磁盘上。
pImage->ReleaseDC();//释放设备上下文。
delete pImage;//析构对象

版权声明:本文为博主原创文章,未经博主允许不得转载。