1. 程式人生 > >淺談MFC中BitBlt與StretchDIBits的差別

淺談MFC中BitBlt與StretchDIBits的差別

一、基礎知識

1.BitBlt
BitBlt 用於從原裝置中複製點陣圖到目標裝置,語法格式如下:
BOOL BitBlt(
HDC hdcDest, // handle to destination DC
int nXDest, // 目標矩形區域的左上角x軸座標點。
int nYDest, // 目標矩形區域的左上角y軸座標點。
int nWidth, // 在目標裝置中繪製點陣圖的寬度。
int nHeight, // 在目標裝置中繪製點陣圖的高度。
HDC hdcSrc, // 源裝置上下文物件指標。
int nXSrc, // 源裝置上下文的起點x軸座標,函式從該起點複製點陣圖到目標裝置。
int nYSrc, // 源裝置上下文的起點y軸座標,函式從該起點複製點陣圖到目標裝置。
DWORD dwRop // 光柵操作程式碼
);
dwRop有如下選擇:
BLACKNESS 使用黑色填充目標區域
DSTINVERT 目標矩陣區域顏色取反
MERGECOPY 使用與運算組合原裝置矩形區域的顏色和目標裝置的畫刷
MERGEPAINT 使用或運算將反向的源矩形區域的顏色和目標矩形區域的顏色合併
NOTSRCCOPY 複製源裝置區域的反色到目標裝置中
NOTSRCERASE 使用或運算組合源裝置區域與目標裝置區域的顏色,然後對結果顏色取反
PATCOPY 複製源裝置當前選中的畫刷到目標裝置
PATINVERT 使用異或運算組合目標裝置選中的畫刷和目標裝置區域的顏色
PATPAINT 通過或運算組合目標區域當前選中的畫刷和源裝置區域反轉的顏色
SRCAND 使用與運算組合源裝置和目標裝置區域的顏色
SRCCOPY 直接複製源裝置區域到目標裝置中
SRCERASE 使用與運算組合目標裝置區域的反色與源裝置區域的顏色
SRCINVERT 使用異或運算組合源裝置區域顏色和目標裝置區域顏色
SRCPAINT 使用或運算組合源裝置區域顏色和目標裝置區域顏色
WHITENESS 使用白色填充目標區域

2.StretchDIBits
int StretchDIBits(
HDC hdc, // handle to DC
int XDest, // 指定目標矩形左上角的X軸座標,按邏輯單位表示座標。
int YDest, // 指定目標矩形左上角的Y軸座標,按邏輯單位表示座標。
int nDestWidth, // 指定目標矩形的寬度,按邏輯單位表示寬度。
int nDestHeight, // 指定目標矩形的高度,按邏輯單位表示高度。
int XSrc, // 指向源矩形區域左上角的X軸座標,按邏輯單位表示座標。
int YSrc, // 指向源矩形區域左上角的Y軸座標,按邏輯單位表示座標。
int nSrcWidth, // 指定源矩形的寬度,按邏輯單位表示寬度。
int nSrcHeight, // 指向源矩形區域左上角的Y軸座標,按邏輯單位表示座標。
CONST VOID *lpBits, // 指向DIB位的指標,這些位的值按位元組型別陣列儲存
CONST BITMAPINFO *lpBitsInfo, // 指向BITMAPINFO結構的指標,該結構包含有關DIB方面的資訊。
UINT iUsage, // 表示是否提供了BITMAPINFO結構中的成員bmiColors,如果提供了,那麼該bmiColors是否包含了明確的RGB值或索引。
DWORD dwRop // 光柵操作程式碼
);
BITMAPINFO結構具有如下形式:
typedef struct tagBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
其中bmiHeader.biHeight表示影象的高度,但是它可以負值,例如:如果影象大小為512*512,那麼
bmiHeader.biHeight = 512 則影象原點在左下角;
bmiHeader.biHeight = -512 則影象原點在左上角;
由於通常影象處理中使用的座標系座標原點在影象左上角,所以,通常要將bmiHeader.biHeight設定為負值,使用時較為方便。
(此描述引用來自部落格http://blog.csdn.net/bflong/article/details/47298997)

3.區別
StretchBlt是拉伸影象拷貝。引數中比bitblt多。這個是對映模式,從源dc的nXOriginSrc,nYOrignSrc對映到目標dc的nXOriginDest, nYOriginDest。源dc的範圍和目標dc的範圍執行拉伸隱射。可以看成一個空間幾何的四稜椎臺體。從一個截面對映到另外一個截面。如果2個截面面積相等,那就是1對1的資料拷貝,如果不是,就按照比例計算擬合數據。

這個需要 SetStretchBltMode 設定拉伸拷貝的資料複合模式。也就是資料擬合的計算方法。

相同的引數 DWORD dwRop 表示光柵計算模式,從源資料-》目標資料的複合,比如拷貝、按位與或等二進位制運算。

簡單說,bitblt直接按你指定的大小輸出源dc到目標dc,而strechblt會調整你源dc大小,使之適應你所指定的目標dc大小,再輸出。

也就是說,strechblt輸出的圖總是完整的,而且充滿你指定的目標DC區域,而bitblt則可能輸出的圖是不完整的,也可能無法充滿目標dc制定區域。

4.其他
CImage類是ATL和MFC共用的一個類,其標頭檔案為atlimage.h,主要用於圖片檔案的開啟,顯示與儲存。
CImage::Create
建立以CImage點陣圖並將它附加到以前構造的CImage物件。
Bool Create(int nWidth, int nHeight, int nBPP, DWORD dwFlags = 0);
引數:
nWidth:CImage 點陣圖的寬度,以畫素為單位。
nHeight:CImage 點陣圖的高度,均以畫素。 如果 nHeight 為正數的,點陣圖是一個從下到上DIB,並且原點是左下角。 如果 nHeight 為負,點陣圖是一組DIB,並且原點為左上角。
nBPP:位的數目每在點陣圖的畫素。 通常4,8,16,24或32。 可以是1單色點陣圖或掩碼。
dwFlags:指定點陣圖物件是否具有一個alpha通道。
CImage::Save
用於將影象儲存到指定的流或檔案在磁碟上。
HRESULT Save(IStream* pStream, REFGUID guidFileType ) const throw();
HRESULT Save( LPCTSTR pszFileName, REFGUID guidFileType= GUID_NULL) const throw();
引數:
pStream
對包含檔案影象資料的IStream COM物件的指標。
pszFileName
對檔名的指標的影象。
guidFileType
儲存影象的檔案型別。 可以是如下內容之一:
ImageFormatBMP 一個未壓縮的點陣圖影象。
ImageFormatPNG 可移植網路映像(PNG)壓縮影象。
ImageFormatJPEG JPEG壓縮影象。
ImageFormatGIF GIF壓縮影象。
CImage::ReleaseDC
釋放裝置上下文。

二、函式應用

裝置中的需求功能包括擷取影象;在影象上進行繪圖操作,並擷取帶繪圖的影象等功能。
簡單的擷取影象就可以使用函式BitBlt完成,並儲存到本地。
對於需要擷取帶繪圖的影象時,可以使用StretchDIBits函式進行操作,設定PBITMAPINFO結構體引數等。
CImage *pImage = new CImage;//建立一個CImage物件的指標
pImage->Create(512, 512, 32, 0);//建立以CImage點陣圖並將它附加到以前構造的CImage物件。
CDC* m_pMemDC;//Windows使用與裝置無關的圖形裝置環境(DC :Device Context) 進行顯示 。MFC基 礎類庫定義了裝置環境物件類—-CDC類。
BYTE* m_pImg;
if()
{
BitBlt(pImage->GetDC(), 0, 0, 512,512, m_pMemDC->m_hDC, 0, 0, SRCCOPY);
}
else
{
StretchDIBits(pImage->GetDC(), 0, 0, 512, 512, 0, 0, 512, 512, m_pImg, (PBITMAPINFO)&m_cImgBmpInfo, DIB_RGB_COLORS, SRCCOPY);
}
pImage->Save(strFolderPath);//用於將影象儲存到指定的流或檔案在磁碟上。
pImage->ReleaseDC();//釋放裝置上下文。
delete pImage;//析構物件