資源描述:
《用VC編程實(shí)現(xiàn)BMP圖像裁切》由會員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫。
1、5.5用VC編程實(shí)現(xiàn)BMP圖像裁切隨著計算電子技術(shù)和計算機(jī)技術(shù)的發(fā)展,數(shù)字圖像處理進(jìn)入高速發(fā)展時期,許多成熟的圖像處理軟件如雨后春筍般層出不窮。在大多數(shù)圖像處理軟件中都有圖像裁切功能,用它能夠快速提取感興趣區(qū)域,去掉多余的圖像內(nèi)容。那么怎樣編程實(shí)現(xiàn)圖像裁切呢,下面以BMP圖像為例介紹一下如何用VC實(shí)現(xiàn)圖像裁切。先介紹第一種方法,將圖像數(shù)據(jù)全部讀入內(nèi)存,然后將感興趣區(qū)域裁切下來。在許多數(shù)字圖像處理的書中都有關(guān)于BMP圖像存儲結(jié)構(gòu)的章節(jié),這里就不再詳細(xì)介紹了。BMP文件一般分為四個部分:位圖頭文件、位圖信息頭、調(diào)色板和圖像數(shù)據(jù)。圖像裁切要用到位圖信
2、息頭中的幾個參數(shù)值:biWidth(圖像寬度)、biHeight(圖像高度)、biBitCount(每個像素的位數(shù))、biSizeImage(圖像長度)。圖像裁切首先要確定裁切區(qū)域內(nèi)每個像素在整幅圖像中的位置,我們以裁切區(qū)域中心點(diǎn)像素位置起算,要注意的是圖像數(shù)據(jù)的存儲是從最下面一行的左邊開始的。如下圖,Height是圖像高,Width是圖像寬,ctPoint是裁切區(qū)域中心點(diǎn)坐標(biāo),dwX和dwY分別是裁切區(qū)域的寬和高。以256色圖像為例(每個像素占一個字節(jié)),裁切區(qū)域左下角像素(也就是裁切后圖像的第一個像素)位置為(Height-ctPoint.
3、y-dwY/2-1)×Width+ctPoint.x-dwX/2,左下角像素位置確定了,裁切區(qū)域內(nèi)的其他像素位置就很容易確定。確定了裁切區(qū)域內(nèi)每個像素的位置后,就可以把這些像素的值賦給裁切后圖像的相應(yīng)像素。裁切后圖像的位圖信息頭和調(diào)色板只要從原圖像數(shù)據(jù)中拷貝就可以了,修改信息頭中圖像寬、高和長度值為裁切后的值。按照上面的思路筆者用VC++6.0編寫了一個圖像裁切函數(shù)ClipDIB(),該函數(shù)首先計算裁切區(qū)域圖像數(shù)據(jù)的大小,為裁切后的圖像分配內(nèi)存,然后將原圖像的信息頭、調(diào)色板拷貝給裁切后的圖像,最后將原圖像中裁切區(qū)域內(nèi)的像素值賦給裁切后影像。HD
4、IBCBMP_ViewView::ClipDIB(HDIBhDib,CPointctpoint,DWORDdwX,DWORDdwY){//假如圖像為空則返回if(hDib==NULL){returnNULL;}//獲得圖像指針LPSTRlpDIB=(LPSTR)::GlobalLock((HGLOBAL)hDib);//圖像信息頭指針LPBITMAPINFOHEADERlpBMIH=(LPBITMAPINFOHEADER)lpDIB;//如果裁切中心點(diǎn)超出圖像范圍if(ctpoint.x>(int)DIBWidth(lpDIB)
5、
6、ctpoin
7、t.y>(int)DIBHeight(lpDIB)){AfxMessageBox("中心點(diǎn)不在圖像范圍內(nèi)");returnNULL;}DWORDdwxSave;//實(shí)際影像保存的寬度DWORDdwBitsSize;//裁切后圖像區(qū)域大小if((int(ctpoint.x-dwX/2)<0)&&(int(ctpoint.y-dwY/2)<0)&&(ctpoint.x+dwX/2)>DIBWidth(lpDIB)&&(ctpoint.y+dwY/2)>DIBHeight(lpDIB)){AfxMessageBox("裁切區(qū)域超出圖像范圍");ret
8、urnNULL;}//實(shí)際影像保存的寬度為4字節(jié)的整數(shù)倍dwxSave=(dwX*lpBMIH->biBitCount+31)/32*4;//實(shí)際影像塊的大小dwBitsSize=dwxSave*dwY;//裁切后的DIB圖像大?。ú话募^)DWORDdwClipedSize;dwClipedSize=sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIB)+dwBitsSize;//為裁切后的DIB分配內(nèi)存HDIBhClipedDIB;hClipedDIB=(HDIB)::GlobalAlloc(GMEM_M
9、OVEABLE
10、GMEM_ZEROINIT,dwClipedSize);//獲得圖像指針LPSTRlpClipedDIB=(LPSTR)::GlobalLock((HGLOBAL)hClipedDIB);//拷貝信息頭和調(diào)色板memcpy(lpClipedDIB,lpDIB,sizeof(BITMAPINFOHEADER)+PaletteSize(lpDIB));//修改信息頭中影像長、寬、長度LPBITMAPINFOHEADERpClipedDibIFH=(LPBITMAPINFOHEADER)lpClipedDIB;pClipedDibIF
11、H->biWidth=dwX;pClipedDibIFH->biHeight=dwY;pClipedDibIFH->biSizeImage=dwX*d