浅谈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;//析构对象

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

时间: 2024-11-05 04:21:11

浅谈MFC中BitBlt与StretchDIBits的区别的相关文章

转 浅谈C++中指针和引用的区别

浅谈C++中指针和引用的区别 浅谈C++中指针和引用的区别 指针和引用在C++中很常用,但是对于它们之间的区别很多初学者都不是太熟悉,下面来谈谈他们2者之间的区别和用法. 1.指针和引用的定义和性质区别: (1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元:而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已.如: int a=1;int *p=&a; int a=1;int &b=a; 上面定义了一个整形变量和一个指针变量p,该指针变量指向a

浅谈C#中堆和栈的区别(附上图解)

线程堆栈:简称栈 Stack 托管堆: 简称堆 Heap 使用.Net框架开发程序的时候,我们无需关心内存分配问题,因为有GC这个大管家给我们料理一切.如果我们写出如下两段代码: 代码段1: public int AddFive(int pValue) { int result; result = pValue + 5; return result; } 代码段2: public class MyInt { public int MyValue; } public MyInt AddFive(i

浅谈Java中set.map.List的区别

就学习经验,浅谈Java中的Set,List,Map的区别,对JAVA的集合的理解是想对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java.util包中! JAVA集合只能存放引用类型的的数据,不能存放基本数据类型. JAVA集合主要分为三种类型: Set(集) List(列表) Map(映射) Collection 接口 :Collection是最基本的集合接口,声明了适用

浅谈HTTP中Get与Post的区别_转

可参考:HTTP请求中POST与GET的区别 Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作.到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息. 1.根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的

浅谈JavaScript中typeof与instanceof的区别

  首先,我们从其常规定义入手:       instanceof 运算符可以用来判断某个构造函数的 prototype 属性是否存在另外一个要检测对象的原型链上.(需要注意的一点是:prototype(原型链)的属性值有可能会改变).     typeof操作符返回一个字符串,表示未经求值的操作数(unevaluated operand)的类型. 此处引入topeof的一些特别之处,以便在区分用instanceof 还是typeof是做出判断: 注意:在通过typeof处理"其他任何对象&qu

浅谈HTTP中Get与Post的区别

一般在浏览器中输入网址访问资源都是通过get方式:在Form提交中,可以通过method指定提交方式为get或者post,默认为get提交. Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作.到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而P

浅谈C++中指针和引用的区别

指针和引用在C++中很常用,但是对于它们之间的区别很多初学者都不是太熟悉,下面来谈谈他们2者之间的区别和用法. 1.指针和引用的定义和性质区别: (1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元:而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已.如: int a=1;int *p=&a; int a=1;int &b=a; 上面定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址. 而下面2句定义了一

转 浅谈HTTP中Get与Post的区别

原文:http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE.URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作.到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于

浅谈C#中const、static readonly区别

const 编译时常量 static readonly 运行时常量 直接上代码 1.新建一个类库BLL->添加类Teacher 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace BLL 8 { 9 public class Teacher 10 { 11 public