GDI 總結二: 位圖的繪製

         在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);  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章