在GDI有一個特點: 就是所有的圖片繪製,都是通過DC來完成的。DC之間是可以相互傳遞的。
兩個DC之中的圖形 通過DC--->DC 來相互傳遞信息。
無論
位圖--->屏幕
位圖--->位圖
屏幕---->位圖
屏幕----->屏幕
他們所使用的都是DC-->DC之間的傳遞。
其關鍵點便是:
如何獲得各自的DC
對於屏幕:
直接使用GetDC() ReleaseDC() 便可
::GetDC() 返回的是CDC*
對於圖片:
CBitmap 不支持DC
CImage 獲得DC
- CImage img;
- img.Load(imageFilePath);
- CDC *pDC;
- pDC=CDC::FromHandle(img.GetDC());
- // use pDC here
- 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
如下例:
- CBitmap bmp;
- bmp.LoadBitmap(IDI_BITMAP);
- CDC memDC;
- memDC.CreateCompatibleDC(pDC);
- memDC.SelectObject(&bmp);
- pDC->BitBlt(0,0,nWidth,nHeight,&memDC,0,0,SRCCOPY);
DC--->DC的傳遞
下面針對各種情況一一給出示例:
1 位圖--->屏幕
- // 位圖到屏幕
- CBitmap bmp;
- BITMAP bm;
- CDC memDC;
- CDC *pDC=GetDC();
- //加載圖片 獲得圖片信息
- bmp.LoadBitmap(IDB_BITMAP);
- bmp.GetBitmap(&bm);
- // 創建與屏幕兼容的DC,並選入位圖
- memDC.CreateCompatibleDC(pDC);
- CBitmap* pOldBmp=(CBitmap *)memDC.SelectObject(&bmp);
- // 將位圖繪製在屏幕中 位圖--->屏幕
- pDC->SetStretchBltMode(COLORONCOLOR);
- pDC->StretchBlt(0,0,100,100,&memDC,bm.bmWidth,bm.bmHeight,SRCCOPY);
- memDC.SelectObject(pOldBmp);
- //釋放資源
- ReleaseDC(pDC);
2
位圖到位圖1-----二者都是CBitmap類對象
- // 位圖到位圖
- // 因爲目的地是位圖,所以先創建一個空白位圖
- // 因爲是位圖與位圖之間的傳遞,所以可以使用兩個內存DC來完成
- // 兩個DC如何兼容? 只要每一個DC都與屏幕DC兼容,則這兩個DC也就互相兼容了
- CBitmap destBmp;
- CBitmap sourceBmp;
- BITMAP bm;
- // 定義源DC 與目的DC對象
- CDC sourceDC;
- CDC destDC;
- // 獲得兼容的屏幕DC
- CDC *pDC=GetDC();
- //加載源圖片
- sourceBmp.LoadBitmap(IDB_BITMAP);
- sourceBmp.GetBitmap(&bm);
- // 創建源DC資源
- sourceDC.CreateCompatibleDC(pDC);
- sourceDC.SelectObject(&sourceBmp);
- // 創建Dest位圖資源
- destBmp.CreateCompatibleBitmap(pDC,bm.bmWidth,bm.bmHeight);
- // 創建DestDC資源
- destDC.CreateCompatibleDC(pDC);
- destDC.SelectObject(&destBmp);
- //位圖到位圖傳遞
- destDC.SetStretchBltMode(HALFTONE);
- destDC.StretchBlt(0,0,bm.bmWidth,bm.bmHeight,&sourceDC,0,0,100,100,SRCCOPY);
- ReleaseDC(pDC);
位圖到位圖2---源位圖爲CImage類
- // 位圖到位圖 2
- // 源位圖爲CImage對象,直接使用CImage對象的成員函數進行傳遞
- CImage sourceImage;
- CBitmap destBmp;
- CDC destDC;
- sourceImage.Load(imageFile);
- // 獲得CImage對象的DC
- CDC *pDC=CDC::FromHandle(sourceImage.GetDC());
- // 創建Dest位圖資源 DestDC
- destDC.CreateCompatibleDC(pDC);
- destDC.SelectObject(&destBmp);
- ::SetStretchBltMode(destDC.m_hDC,HALFTONE);
- ::SetBrushOrgEx(destDC.m_hDC,0,0,NULL);
- // 直接使用CImage成員函數進行傳遞 其實是:CImage封裝了DC之間的傳遞工作
- sourceImage.StretchBlt(&destDC,CRect(0,0,100,100),CRect(0,0,100,100),SRCCOPY);
- // 釋放DC資源
- sourceImage.ReleaseDC();
3 屏幕到位圖
- //屏幕到位圖
- CBitmap destBmp;
- CDC destDC;
- // 獲得兼容的屏幕DC
- CDC *pDC=GetDC();
- // 創建Dest位圖資源
- destBmp.CreateCompatibleBitmap(pDC,100,100);
- // 創建DestDC資源
- destDC.CreateCompatibleDC(pDC);
- destDC.SelectObject(&destBmp);
- //屏幕到位圖傳遞
- destDC.SetStretchBltMode(HALFTONE);
- destDC.StretchBlt(0,0,100,100,pDC,0,0,100,100,SRCCOPY);
- ReleaseDC(pDC);