位图操作和双缓冲机制

位图操作
代码部分:
 CRect rect;
 GetClientRect(rect);
 pDC->SetMapMode(MM_ANISOTROPIC);
 pDC->SetWindowExt(rect.Width(), rect.Height());
 pDC->SetViewportExt(rect.Width(), -rect.Height());
 pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);

CDC MemDC;
 CBitmap NewBitmap, *pOldBitmap;
 NewBitmap.LoadBitmap(IDB_ABOUT);
 BITMAP bmp;  NewBitmap.GetBitmap(&bmp);
 MemDC.CreateCompatibleDC(pDC);
 pOldBitmap = MemDC.SelectObject(&NewBitmap);

MemDC.SetMapMode(MM_ANISOTROPIC);
 MemDC.SetWindowExt(bmp.bmWidth, bmp.bmHeight);

MemDC.SetViewportExt(bmp.bmWidth, -bmp.bmHeight);
 MemDC.SetViewportOrg(bmp.bmWidth/2, bmp.bmHeight);
 pDC->BitBlt(-rect.Width()/2, -rect.Height()/2, rect.Width(), rect.Height(), &MemDC, -bmp.bmWidth/2, -bmp.bmHeight/2, SRCCOPY);  MemDC.SelectObject(pOldBitmap);

双缓冲机制
 CRect rect;
 GetClientRect(&rect);
 pDC->SetMapMode(MM_ANISOTROPIC);
 pDC->SetWindowExt(rect.Width(),rect.Height());
 pDC->SetViewportExt(rect.Width(),-rect.Height());
 pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);

CDC memDC;//声明内存DC
 CBitmap NewBitmap,*pOldBitmap;
 memDC.CreateCompatibleDC(pDC);//创建一个与显示DC兼容的内存DC
 NewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//创建兼容内存位图
 pOldBitmap=memDC.SelectObject(&NewBitmap);//将兼容位图选入内存DC
 memDC.FillSolidRect(rect, RGB(0, 0, 0));//按原来背景色填充客户区,否则是黑色

rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);
 memDC.SetMapMode(MM_ANISOTROPIC);//内存DC自定义坐标系
 memDC.SetWindowExt(rect.Width(),rect.Height());
 memDC.SetViewportExt(rect.Width(),-rect.Height());
 memDC.SetViewportOrg(rect.Width()/2,rect.Height()/2);

DrawObject(&memDC);
 pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,-rect.Width()/2,-rect.Height()/2,SRCCOPY); //将内存DC中的位图拷贝到设备DC
 memDC.SelectObject(pOldBitmap);

两段代码都用到CreateCompatibleDC(),可是它们是有区别的,相关部分看下面

CBitmap::GetBitmap int GetBitmap( BITMAP* pBitMap );
返回值:成功非零,失败零
参数:pBitMap 指向BITMAP结构体的指针,必须是非空
说明:调用这个成员函数来检索一个CBitmap对象的信息。信息通过BITMAP结构体返回

CDC::CreateCompatibleDC  virtual BOOL CreateCompatibleDC( CDC* pDC );
返回值:成功非零,失败零
参数: pDC 一个指向设备上下文的指针。如果是空,函数创建一个与显示设备上下文相兼容的内存设备上下文
说明: 创建一个和pDC指向的设备上下文相兼容的内存设备上下文。一个内存设备上下文是一个代表一个显示面内存块。它可以用来在内存中准备图片,当要拷贝它们到实际的相兼容的设备的上面。
当一个内存设备上下文被创建,GDI自动选择一个1×1单色像素位图。GDI输出函数可以和内存设备上下文一起使用当且仅当一个位图创建并选择到该上下文。
这个函数只能用来为可以支持光栅操作 的设备创建兼容设备上下文。查看CDC:BitBlt成员函数有关在设备上下文间表的传输信息。决定一个设备上下文是否支持光栅操作,要看成员函数::GetDeviceCaps的RC_BITBLT光栅能力。

CBitmap::CreateCompatibleBitmap BOOL CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight );
返回值 成功非零,失败零
参数: pDC 指定设备上下文 nWidth 指定bitmap的像素宽 nHeight 指定bitmap的像素高
说明: 初始化一个与pDC指定的设备相兼容的位图。位图和指定的设备上下文有相同数量的颜色值或相同的格式(每个像素色彩位数相同)。它可以被任何内存设备(与pDC所指定的某个设备相兼容)选为当前位图。
如果pDC是内存设备上下文,位图返回该设备上下文中和当前所选位图具有相同的格式的bitmap。一个“内存设备上下文”是一块代表一个显示面的内存。它可以用来在内存中准备图片,在拷贝它们到实际的相兼容的设备的上面之前。
当一个内存设备上下文被创建了,GDI自动为它选择一个单色的备用bitmap。 由于一个颜色内存设备上下文可以选择彩色或单色位图,CreateCompatibleBitmap函数返回的位图格式并不总是相同的,然而, 一个与nonmemory设备上下文兼容的位图的格式总是在设备的格式中。
当你用CreateCompatibleBitmap函数完成CBitmap对象创建,首先将位图选出设备上下文,然后删除CBitmap对象。

CDC::CreateCompatibleDC和CBitmap::CreateCompatibleBitmap 区别 一个是设备上下文,一个是位图;这是最大的区别

CWnd::Invalidate void Invalidate( BOOL bErase = TRUE );
参数: bErase 指定更新区域内的背景是否被删除
说明: Wnd的整个客户区无效。当WM_PAINT消息出现,客户区被标记为绘画。该地区可以通过ValidateRect和ValidateRgn成员函数在 WM_PAINT消息发生之前验证。
bErase参数指定当更新区域被处理时更新区域内的背景是否被删除。如果bErase是真的,BeginPaint成员函数被调用时背景要删除;如果bErase是假的,背景保持不变。如果bErase适用于任何更新区域的一部分,整个地区(不仅在给定的部分)的背景都要删除。
只要CWnd更新区域并不是空而且没有其他消息的应用程序队列在该窗口,Windows发送WM_PAINT消息。

双缓冲原理是先在内存设备上下文将图形绘制好,然后将它拷到显示设备上下文,它的代码部分要看仔细。

时间: 2024-10-10 17:14:29

位图操作和双缓冲机制的相关文章

VC GDI双缓冲机制绘图防屏幕闪烁实现步骤

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

双缓冲机制简介

一.理解双缓冲机制 1.创建一个画板,和一个图片() 2.将图片设置为画板 3.之后画板将会在该图片上作画 4.之后再将图片放到View提供的画板上显示 二.实例(利用双缓冲机制的画板) public class DrawView extends View { private int view_width = 0; private int view_height = 0; private float prevX = 0; private float prevY = 0; private Path

STM32的bulk双缓冲传输速度的讨论,硬件的坑永远填不完

详情:http://bbs.21ic.com/forum.php?mod=viewthread&tid=109584 USB 1.0的最高12Mbps. USB 2.0的高速模式480Mbps,全速模式12Mbps,低速模式1.5Mbps 而是设置STM32端的USART的波特率.PC与STM32传输速度是以USB1.1的理论速度传输的,是不能设置的. 接收到数据,置NAK->将缓冲区数据拷贝到用户区(用户处理过程)->发ACK通知主机完成了完整的接收可以发送下一个->主机发送下

多线程操作C++ STL vector出现概率coredump问题及尽量避免锁的双缓冲队列

多线程操作全局变量,必须考虑同步问题,否则可能出现数据不一致, 甚至触发coredump. 前段时间, 遇到一个多线程操作了全局的vector的问题,  程序崩了.场景是这样的:某全局配置参数保存在一个vector中,需要定时更新(更新线程), 另外的工作线程去读取配置. 这种场景是非常普遍的. 在该场景中,程序没有枷锁,概率coredump, 实际情况是,服务跑了一段时间后,必然coredump.   很显然, 更新线程执行clear,然后在push_back操作时, 会导致工作线程的vect

MFC双缓冲绘图解决界面闪烁问题

一:为什么会产生界面闪烁? 解释这个之前,我们需要明白的是在MFC里面绘图的消息响应机制,大概的就是如果我们要在某一个 东西上面绘图,比如对话框,单文档等等,就必须先得到图形DC的句柄(handle),然后在指定句柄的基础上进行图形操作,也就是MFC常用的CDC *DC = this->getDC();其中的this就是你想画图的目标. MFC里在消息响应的过程中,WM_PAINT被转变为OnDraw()(单文档 Single Document)或是OnPaint()(对 话框Dialog)之类

VC双缓冲绘图技术介绍

VC双缓冲绘图技术介绍 双缓冲绘图,它是一种基本的图形图像绘图技术.首先,它在内存中创建一个与屏幕绘图区域一致的对象,然后将图形绘制到内存中的这个对象上,最后把这个对象上的图形数据一次性地拷贝并显示到屏幕上.这种技术能够大大地提高绘图的速度,减少卡顿和闪屏的问题. 我们为什么要使用双缓冲技术来进行绘图? 在应用程序开发中,当图像信息数据量很大时,绘图可能需要几秒钟甚至更长的时间,这时,应用程序可能会出现卡顿的现象.另外,如果窗体在响应WM_PAINT消息的同时也要进行复杂的图形处理,那么窗体在重

avalon与双缓冲技术

avalon与双缓冲技术 avalon1.5一个重要技术升级是引进异步渲染.异步渲染在游戏界有一个更专业的名字,叫双缓冲.游戏界要刷新界面与我们刷新浏览器视图,面临的问题是一致的.视图是由许多存在套嵌关系的方块组成,它们每一个的改动,都可能引起reflow(其父节点,其父父节点的大小重新计算),这是造成性能问题的关键. 双缓冲技术的主要原理是:当一个动画争先显示时,程序又在改变它,前面的画面还没显示完,程序又要求重新绘制,这样屏幕就会不停闪烁.为了避免闪烁,可以使用双缓冲技术,将要处理的图片都放

GDI双缓冲绘图

一.简介 在进行复杂图形绘制时,若直接在屏幕DC上进行绘制,则会出现明显的闪烁.闪烁产生的原因是当绘制的图形较为 复杂时,图形绘制过程中就被刷新到屏幕上,导致结果断断续续地显示出来.双缓冲绘图的原理是在另开辟一块内存用于绘制,当所有绘制工作完成后将内存数据一 次性拷贝到屏幕上. 双缓冲绘图步骤: 创建兼容DC(CreateCompatibleDC) 创建兼容位图(CreateCompatibleBitmap) 将兼容位图选入兼容DC(SelectObject) 在兼容DC中进行绘制工作 将兼容D

Win32 GDI 非矩形区域剪裁,双缓冲技术

传统的Win32通过GDI提供图形显示的功能,包括了基本的绘图功能,如画线.方块.椭圆等等,高级功能包括了多边形和Bezier的绘制.这样app就不用关心那些图形学的细节了,有点类似于UNIX上的X-window协议.你信或者不信,那些看上去很花哨的控件,其实就是一笔一划画上去的而已.GDI提供了画笔(用于线条).画刷(用于填充).调色板(用于支持256色显示).字体(用于文字).如果简单的图形不足以表达,你可以使用位图和画布(DC,设备上下文)直接将图像绘制到屏幕上去.此外,GDI还支持一些简