zoukankan      html  css  js  c++  java
  • GDI C++(2) 位图的绘制

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

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

             无论                 

                            位图--->屏幕

                            位图--->位图

                            屏幕---->位图

                            屏幕----->屏幕

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

           

     其关键点便是:

    如何获得各自的DC

     

            对于屏幕:

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

                              ::GetDC() 返回的是CDC* 

                          

            对于图片:

                            CBitmap  不支持DC

                            CImage   获得DC

    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

    如下例:

    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 位图--->屏幕

    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类对象

    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类

     

    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 屏幕到位图          

    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);  
  • 相关阅读:
    常用数据结构之哈希表
    常用数据结构之队列
    常用的数据结构之栈
    常用的数据结构之链表
    Zabbix3.4监控Windows机器CPU使用率
    在Pycharm中导入第三方模块库(诸如:matplotlib、numpy等)
    WARNING: You are using pip version 20.2.4; however, version 20.3.1 is available.
    npm无法安装node-sass的解决方法
    常见的树形结构封装
    Mac安装MySql
  • 原文地址:https://www.cnblogs.com/bigbigtree/p/2343504.html
Copyright © 2011-2022 走看看