内存中绘图 Memdc

CDC MemDC;   //首先定义一个显示设备对象,所有的绘制首先绘制到这块内存中
CBitmap MemBitmap; //定义一个位图对象

//随后建立与屏幕显示兼容的内存显示设备
MemDC.CreateCompatibleDC(NULL);
MemDC.SetStretchBltMode(HALFTONE);

//这时还不能绘图,因为没有地方画
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小
MemBitmap.CreateCompatibleBitmap(&dc /*是dc这个参数,而不是MemDC*/,rectCanvas.Width(),rectCanvas.Height());

//将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);

//这一句只是为了填充一个背景,
MemDC.FillSolidRect(rectCanvas.left,rectCanvas.top,rectCanvas.Width(),rectCanvas.Height(),GetBackgroundColor());

//在MemDC上进行操作,绘制你想要绘制的东西
//...

//将MemDC的图拷贝到屏幕(dc)上进行显示
dc.BitBlt(rectCanvas.left,rectCanvas.top,rectCanvas.Width(), rectCanvas.Height(),&MemDC,0,0,SRCCOPY);

//绘图完成后的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC();

CreateCompatibleBitmap

bitmap.CreateCompatibleBitmap(HDC hdc, int nWidth, int nHeight);

函数功能:该函数创建与指定的设备环境相关的设备兼容的位图。

  参数:

  hdc: 设备环境句柄。

  nWidth:指定位图的宽度,单位为像素。

  nHeight:指定位图的高度,单位为像素。

  返回值:如果函数执行成功,那么返回值是位图的句柄;如果函数执行失败,那么返回值为NULL。若想获取更多错误信息,请调用GetLastError。

备注:由CreateCompatibleBitmap函数创建的位图的颜色格式与由参数hdc标识的设备的颜色格式匹配。该位图可以选入任意一个与原设备兼容的内存设备环境中。由于内存设备环境允许彩色和单色两种位图。因此当指定的设备环境是内存设备环境时,由CreateCompatibleBitmap函数返回的位图格式不一定相同。然而为非内存设备环境创建的兼容位图通常拥有相同的颜色格式,并且使用与指定的设备环境一样的色彩调色板。

 

函数功能:该函数创建一个与指定设备兼容的内存设备上下文环境(DC)。

函数原型:HDC CreateCompatibleDC(HDC hdc);

参数:

hdc:现有设备上下文环境的句柄,如果该句柄为NULL,该函数创建一个与应用程序的当前显示器兼容的内存设备上下文环境。

返回值:如果成功,则返回内存设备上下文环境的句柄;如果失败,则返回值为NULL。

CreateCompatibleDc函数只适用于支持光栅操作的设备,应用程序可以通过调用GetDeviceCaps函数来确定一个设备是否支持这些操作。

当不再需要内存设备上下文环境时,可调用DeleteDc函数删除它。

用双缓冲的话还要再定义一个位图对象吧,然后用CreateCompatibleBitmap建立一个与屏幕显示兼容的位图,再用SelectObject将位图选入到内存显示设备中,不知道是不是这样

首先给出实现的程序,然后再解释,同样是在OnDraw(CDC *pDC)中:
CDC MemDC; //首先定义一个显示设备对象
CBitmap MemBitmap;//定义一个位图对象
//随后建立与屏幕显示兼容的内存显示设备
MemDC.CreateCompatibleDC(NULL);
//这时还不能绘图,因为没有地方画 ^_^
//下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小,也可以自己定义(如:有滚动条时就要大于当前窗口的大小,在BitBlt时决定拷贝内存的哪部分到屏幕上)
MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);

//将位图选入到内存显示设备中
//只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
//先用背景色将位图清除干净,这里我用的是白色作为背景
//你也可以用自己应该用的颜色
MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));
//绘图
MemDC.MoveTo(……);
MemDC.LineTo(……);

//将内存中的图拷贝到屏幕上进行显示
pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);
//绘图完成后的清理
MemBitmap.DeleteObject();
MemDC.DeleteDC();

gdi在sdk应该是很重要的东西,不过嘛自己的水平实在是不怎么够品。长久以来一直都没有认识到 CreateCompatibleDC  的用途到底在这里,不过还好从知道这个东西数起的200天内,我终于还是晓得一些关于这个函数或者说内存dc存在的意义了。

在这种情况下,假如你要对屏幕进行比较多的gdi函数操作,如果每一步操作都直接对屏幕dc进行操作,那出现的大多数可能性都是屏幕的闪烁。一个很好的解决方法就是使用内存dc,将这些操作全部先在内存dc上操作,然后依次性在屏幕上进行操作。

例如:如果你单单使用bitblt在屏幕上拷贝一个图,那可以直接使用屏幕的dc。但是如果你要先设置背景(fillrect)然后再bitblt的话,这就涉及到两个屏幕dc的操作,这样的话屏幕很容易闪烁。

bitblt()用法

在VC中显示位图常用取BitBlt()方法,它是将一幅位图从一个设备场景复制到另一个。源和目标DC相互间必须兼容。
虽然此方法的功能是这样的,但是我一直没有理解网上一些例子代码,不知道其用到的各DC和位图如何得到,及它们之间的关系。
今天工作中要将一些位图显示到窗口中,所以重要学习了一下。
我已经将要用的位图导入到工程资源中,所以我可以用:
        CBitmap cbmp;
        cbmp.LoadBitmap(IDB_BMP1);
这样得到一个CBitmap对象。
然后:
        BITMAP bitmap;
        cbmp.GetBitmap(&bitmap);
这样得到一个BITMAP对象,之所以要得到此对象是因为从其中可以得到位图的大小数据。
然后计算得到要在什么位置显示此位图(可以放在一个CRect rect;对象中)。

然后显示此位图,这是最重要的一步:
         CDC dcMemory;
         dcMemory.CreateCompatibleDC(pDC);
         hOldBitmap = dcMemory.SelectObject(&cbmp);
          pDC->BitBlt(rect.left,
                             rect.top,
                             bitmap.bmWidth,
                             bitmap.bmHeight,
                             &dcMemory,
                             0,0,
                             SRCCOPY);
其中pDC是一个CDC*,是将要在其中显示位图的设备环境。

这样位图就已经显示出来了,但是还要释放资源
        cbmp.DeleteObject();
        dcMemory.SelectObject(hOldBitmap);
        dcMemory.DeleteDC();
其中,要将临时设备环境选择入初始时位图,否则将不能正确释放!!

Bitblt作用将某一内存块的数据传送到另一内存块,前一内存块被称为"源",后一内存块被称为"目标"图象程序开发者使用Blit的函数在内存中将某页面上的一幅位图经过一定的变换转移到另一个页面上
原形说明:
Declare Function BitBlt Lib "gdi32" Alias "BitBlt"(ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
hDestDC As Long, //目标设备环境的句柄
x As Long, //目标设备环境的矩形区域的左上角的x坐标
y As Long, //目标设备环境的矩形区域的左上角的y坐标
nWidth As Long, //目标设备环境的矩形区域的宽度值
nHeight As Long, //目标设备环境的矩形区域的高度值
hSrcDC As Long, //源设备环境的句柄
xSrc As Long, //源设备环境的矩形区域的左上角的x坐标
ySrc As Long, //源设备环境的矩形区域的左上角的y坐标
dwRop As Long, //光栅操作符
dwRop参数是光栅操作代码(Rop),它是指源位图与目标位图以及图案刷的颜色值进行布尔运算的方式,以下列出了常用的光栅操作码及含义
BLACKNESS 用黑色填充目标矩形区域.
DSTINVERT 将目标矩形图象进行反相. 
MERGECOPY 将源矩形图象与指定的图案刷(Pattern)进行布尔"与"运算. 
MERGEPAINT 将源矩形图形经过反相后,与目标矩形图象进行布尔"或"运算.
NOTSRCCOPY 将源矩形图象经过反相后,复制到目标矩形上.
NOTSRCERASE 先将源矩形图象与目标矩形图象进行布尔"或"运算,然后再将得图象进行反相.
PATCOPY 将指定的图案刷复制到目标矩形上.
PATINVERT 将指定的图案刷与目标矩形图象进行布尔"异或"运算.
PATPAINT 先将源矩形图象进行反相,与指定的图案刷进行布尔"或"运算,再与目标矩形图象进行布尔"或"运算SRCAND 将源矩形图象与目标矩形图象进行布尔"与"运算.
SRCCOPY 将源矩形图象直接复制到目标矩形上.
SRCERASE 将目标矩形图象进行反相,再与源矩形图象进行布尔"与"运算.
SRCINVERT 将源矩形图象与目标矩形图象进行布尔"异或"运算.
SRCPAINT 将源矩形图象与目标矩形图象进行布尔"或"运算.
WHITENESS 用白色填充目标矩形区域.

内存中绘图 Memdc相关推荐

  1. MFC在内存DC中绘图

    MFC在内存DC中绘图 文章目录 前言 一.什么是DC? 定义 DC对象介绍 二.绘图步骤 声明DC 选择DC对象 开始绘图 保存及显示 三.示例 四.总结 前言 因为用MFC框架做软件开发,前前后后 ...

  2. mxd2 计算机内存不足,错误:无法将图元文件映射到内存中。 内存不足

    错误:无法将图元文件映射到内存中. 内存不足 错误消息 导出或打印大型地图时,显示以下错误消息. "无法将图元文件映射到内存中. 内存不足" 这可以防止创建输出文件并删除临时的增强 ...

  3. 计算机程序必须装载哪,计算机程序必须装载到内存中才能执行

    正确答案: D 计算机程序必须装载到内存中才能执行 题目:关于计算机的描述,正确的是( ). 解析:计算机的中央处理器CPU包括运算器.控制器:硬盘属于存储器:计算机键盘按功能分为主键盘区.数字键区. ...

  4. python在内存中处理图片

    目录 python在内存中处理图片 1. 获取gif图片第一帧,添加文字,获取图片的base64和md5 2. pyplot绘图后,获取图片的base64和md5 附1. python2.7 pip安 ...

  5. Win32编程之从内存中加载位图,并显示到hdc上

    近期在项目中遇到一个问题,如何在实现从内存中加载RBG帧数据,然后提交到hdc上显示,这里假设大家对win32程序已经很熟了,有了相关的框架,如果不熟的小伙伴可以看我的老师编写的一本书<游戏程序 ...

  6. python slice是共享内存吗_在共享内存中使用numpy数组进行多处理

    在共享内存中使用numpy数组进行多处理 我希望在共享内存中使用numpy数组,以便与多处理模块一起使用.困难之处在于它像一个numpy数组一样使用,而不仅仅是作为一个ctype数组使用.from m ...

  7. 整数中内存中的保存方式:大端、小端

    一个数在计算机内存中的保存方式是大端法表示还是小端法表示? 首先C++当中并没有规定我们这个内存中,整数在内存中是采用大端法还是小端法表示.所以在编写程序的时候这一点并不是很重要. 但是如果编写一个程 ...

  8. C:内存中供用户使用的存储空间

    内存中供用户使用的存储空间可分为: 代码区:存代码的地方. 常量区:存常量的地方. 静态存储区:存变量的地方. 动态存储区:存变量的地方. 存变量的分为静态存储和动态存储两个区: "静态&q ...

  9. OpenCV中图像以Mat类型保存时各通道数据在内存中的组织形式及python代码访问各通道数据的简要方式...

    OpenCV中图像以Mat类型保存时各通道数据在内存中的组织形式及python代码访问各通道数据的简要方式 以最简单的4 x 5三通道图像为例,其在内存中Mat类型的数据组织形式如下: 每一行的每一列 ...

最新文章

  1. SystemProperities
  2. 《Oracle数据库管理与维护实战》——2.11 Oracle数据字典
  3. 将数字字符串转换成逗号分隔的数字串,即从右边开始每三个数字用逗号分隔
  4. Python程序开发——第四章 字典与集合
  5. 利用modelarts和物体检测方式识别验证码
  6. Webpack4 学习笔记二 CSS模块转换
  7. web of science,SSCI索引,带你入门!
  8. win10如何安装Java虚拟机_vmware 安装win10虚拟机
  9. 简明C语言教程(七)scanf 用法
  10. gitLab私服-转帖记录
  11. 错误请联系管理员文件 index.php,GS登录报错,提示【访问权限失败,请联系管理员处理】...
  12. 将手机流氓软件彻底赶出去
  13. matlab求两向量夹角_【求精干货】高中数学知识点总结归纳高一学生必须掌握
  14. 【我的渲染技术进阶之旅】你知道数字图像处理的标准图上的女孩子是谁吗?背后的故事你了解吗?为啥这张名为Lenna的图会成为数字图像处理的标准图呢?
  15. 【第99题】JAVA高级技术-网络编程18(简易聊天室13:聊天室服务端)
  16. 如何让搜搜soso收录我的网站
  17. Tensorflow让神经网络自动创造音乐
  18. 零知识证明 - Groth16算法介绍
  19. Stlink固件更新问题“ST-Link is not in the dfu mode Please restart it“的解决方法
  20. 哈工大深圳计算机学院复试分数线,哈尔滨工业大学深圳研究生院复试线:2011哈尔滨工业大学深圳研究生院复试分数线...

热门文章

  1. 最新虚拟机VMware 下载安装
  2. python tkinter怎么读_Tkinter GUI与阅读系列
  3. python遍历文件_python遍历目录文件脚本的示例
  4. 不等号属于不等式吗_初中数学——中考知识3【方程与不等式(基础)】
  5. mfc exe 在繁体系统 乱码_成都市招标文件编制及备案系统使用技巧问答
  6. 我有单片机,你有酒吗?
  7. 基于xilinx vivado的XDMA IP的使用详解
  8. 中文路径_中文分词的原理、方法与工具
  9. braintree php 开发,php – 如何为使用Braintree和静态方法调用的端点编写集成测试...
  10. php面向对象引用文件,PHP面向对象之对象和引用