博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GDI C++(2) 位图的绘制
阅读量:7283 次
发布时间:2019-06-30

本文共 3127 字,大约阅读时间需要 10 分钟。

在GDI有一个特点: 就是所有的图片绘制,都是通过DC来完成的。DC之间是可以相互传递的。

                                              两个DC之中的图形  通过DC--->DC  来相互传递信息。

         无论                 

                        位图--->屏幕

                        位图--->位图

                        屏幕---->位图

                        屏幕----->屏幕

        他们所使用的都是DC-->DC之间的传递。

       

 其关键点便是:

如何获得各自的DC

 

        对于屏幕:

                          直接使用GetDC()    ReleaseDC() 便可

                          ::GetDC() 返回的是CDC* 

                      

        对于图片:

                        CBitmap  不支持DC

                        CImage   获得DC

[cpp] 
  1. CImage img;  
  2. img.Load(imageFilePath);  
  3.   
  4. CDC *pDC;  
  5. pDC=CDC::FromHandle(img.GetDC());  
  6.   
  7. // use  pDC here  
  8.   
  9.   
  10. img.ReleaseDC();  

     

                      注意:

                                ::GetDC() 返回的是CDC* 

                                 而CImage::GetDC() 返回的HDC

 

对图像进行操作

 

           ::GetDC() 所获得的是屏幕的DC, 使用此DC ,可以对屏幕进行绘图。

 

           如果我们想在某一个位图的基础上,再次绘图的话,便不能简单的使用::GetDC()了,因为它只是负责在屏幕上绘图。

           那怎么办呢?

           既然所有的绘图都是在DC上进行绘图,所以我们必须把这个位图选择进DC,这样对DC操作,就相当直接对位图进行操作

           pDC->SelectObject(&bmp):

           // use pDC to draw orthers in the bmp

 

构造内存DC

           一般我们为了避免闪烁等现象,需要构造内存DC ,然后再DC上进行绘制,绘制完毕后,通过DC之间的传递,将图像再绘制到屏幕中去。

           CDC memDC; 只是创建了一个CDC对象,还没有创建DC资源

            memDC.CreateCompatibleDC(pDC);   才是真正创建DC资源。

           创建兼容DC是关键,其关键之处在于要创建的DC与哪个现有的DC兼容。

           因为内存DC只是个中介,它必须要将其DC中的图像传递到其它DC中(目的DC),才会体现其价值。

           而DC 与 DC之间可以传递信息的前提是:两DC是兼容的。

           据此可知: 内存DC要兼容目的DC

如下例:

[cpp] 
  1. CBitmap bmp;  
  2. bmp.LoadBitmap(IDI_BITMAP);  
  3.   
  4. CDC memDC;  
  5. memDC.CreateCompatibleDC(pDC);  
  6. memDC.SelectObject(&bmp);  
  7.   
  8. pDC->BitBlt(0,0,nWidth,nHeight,&memDC,0,0,SRCCOPY);  

 

 

DC--->DC的传递

下面针对各种情况一一给出示例:

 

1 位图--->屏幕

[cpp] 
  1. // 位图到屏幕  
  2.   
  3.   
  4. CBitmap bmp;  
  5. BITMAP bm;  
  6. CDC memDC;  
  7.   
  8. CDC *pDC=GetDC();  
  9.   
  10. //加载图片 获得图片信息  
  11. bmp.LoadBitmap(IDB_BITMAP);  
  12. bmp.GetBitmap(&bm);  
  13.   
  14. // 创建与屏幕兼容的DC,并选入位图  
  15. memDC.CreateCompatibleDC(pDC);  
  16. CBitmap* pOldBmp=(CBitmap *)memDC.SelectObject(&bmp);  
  17.   
  18. // 将位图绘制在屏幕中  位图--->屏幕  
  19. pDC->SetStretchBltMode(COLORONCOLOR);  
  20. pDC->StretchBlt(0,0,100,100,&memDC,bm.bmWidth,bm.bmHeight,SRCCOPY);  
  21.   
  22. memDC.SelectObject(pOldBmp);  
  23.   
  24. //释放资源  
  25. ReleaseDC(pDC);  

 

2

位图到位图1-----二者都是CBitmap类对象

[cpp] 
  1. // 位图到位图  
  2. // 因为目的地是位图,所以先创建一个空白位图  
  3. // 因为是位图与位图之间的传递,所以可以使用两个内存DC来完成  
  4. // 两个DC如何兼容? 只要每一个DC都与屏幕DC兼容,则这两个DC也就互相兼容了  
  5.   
  6.   
  7. CBitmap destBmp;  
  8. CBitmap sourceBmp;  
  9. BITMAP bm;  
  10.   
  11. // 定义源DC  与目的DC对象  
  12. CDC  sourceDC;  
  13. CDC  destDC;  
  14.   
  15. // 获得兼容的屏幕DC  
  16. CDC *pDC=GetDC();  
  17.   
  18. //加载源图片  
  19. sourceBmp.LoadBitmap(IDB_BITMAP);  
  20. sourceBmp.GetBitmap(&bm);  
  21.   
  22. // 创建源DC资源  
  23. sourceDC.CreateCompatibleDC(pDC);  
  24. sourceDC.SelectObject(&sourceBmp);  
  25.   
  26. // 创建Dest位图资源  
  27. destBmp.CreateCompatibleBitmap(pDC,bm.bmWidth,bm.bmHeight);  
  28. // 创建DestDC资源  
  29. destDC.CreateCompatibleDC(pDC);  
  30. destDC.SelectObject(&destBmp);  
  31.   
  32. //位图到位图传递  
  33. destDC.SetStretchBltMode(HALFTONE);  
  34. destDC.StretchBlt(0,0,bm.bmWidth,bm.bmHeight,&sourceDC,0,0,100,100,SRCCOPY);  
  35.   
  36. ReleaseDC(pDC);  

位图到位图2---源位图为CImage类

 

[cpp] 
  1. // 位图到位图 2  
  2. // 源位图为CImage对象,直接使用CImage对象的成员函数进行传递  
  3.   
  4.   
  5. CImage sourceImage;  
  6. CBitmap destBmp;  
  7. CDC destDC;  
  8.   
  9. sourceImage.Load(imageFile);  
  10.   
  11.   
  12. // 获得CImage对象的DC  
  13. CDC *pDC=CDC::FromHandle(sourceImage.GetDC());  
  14. // 创建Dest位图资源  DestDC  
  15. destDC.CreateCompatibleDC(pDC);  
  16. destDC.SelectObject(&destBmp);  
  17.   
  18. ::SetStretchBltMode(destDC.m_hDC,HALFTONE);  
  19. ::SetBrushOrgEx(destDC.m_hDC,0,0,NULL);  
  20.   
  21. //  直接使用CImage成员函数进行传递  其实是:CImage封装了DC之间的传递工作  
  22. sourceImage.StretchBlt(&destDC,CRect(0,0,100,100),CRect(0,0,100,100),SRCCOPY);  
  23.   
  24. // 释放DC资源  
  25. sourceImage.ReleaseDC();  

 

3 屏幕到位图          

[cpp] 
  1. //屏幕到位图  
  2.   
  3. CBitmap destBmp;  
  4. CDC  destDC;  
  5.   
  6. // 获得兼容的屏幕DC  
  7. CDC *pDC=GetDC();  
  8.   
  9. // 创建Dest位图资源  
  10. destBmp.CreateCompatibleBitmap(pDC,100,100);  
  11. // 创建DestDC资源  
  12. destDC.CreateCompatibleDC(pDC);  
  13. destDC.SelectObject(&destBmp);  
  14.   
  15. //屏幕到位图传递  
  16. destDC.SetStretchBltMode(HALFTONE);  
  17. destDC.StretchBlt(0,0,100,100,pDC,0,0,100,100,SRCCOPY);  
  18.   
  19. ReleaseDC(pDC);  

转载地址:http://vvzjm.baihongyu.com/

你可能感兴趣的文章
[MySQL源码] Innodb如何处理auto_inc值
查看>>
Git(进击学习:远程仓库操作)-V3.0
查看>>
mysql常用基础操作语法(九)~~外连接查询【命令行模式】
查看>>
lamp lnmp lnamp区别
查看>>
Shell 历史记录异地留痕审计与监控
查看>>
机器学习理论研究方法探讨
查看>>
日志服务(原SLS)新功能发布(15)--控制台支持查看协同消费组(ConsumerGroup)消费进度...
查看>>
深入Protobuf源码-概述、使用以及代码生成实现
查看>>
双网卡同时上网
查看>>
LVM学习之逻辑卷及卷组缩小空间
查看>>
NHibernate 2 学习
查看>>
iOS中大流中的自定义cell 技术分享
查看>>
SGA Heap size 2098K exceeds notification threshold (2048K)的问题
查看>>
ListView 适配器实现getviewtypecount() 数组越界IndexOutOfBoundException
查看>>
“插入排序”算法Java语言的实现与详解
查看>>
《Netty 权威指南》—— AIO版本时间服务器运行结果
查看>>
桶排序算法
查看>>
requirejs:杏仁的优化(almond)
查看>>
CSS样式----图文详解:css样式表和选择器
查看>>
绘制波形图
查看>>