VC++和VC++.NET中与图像处理有关的几个概念、结构和类
| 最近一直在看VC++有關(guān)圖像處理方面的書(shū),終于把以前一直混淆的幾個(gè)概念、結(jié)構(gòu)和類(lèi)弄清楚了,特整理如下。如有錯(cuò)誤,請(qǐng)大家批評(píng)指正,不勝感激。下一步想好好學(xué)習(xí)學(xué)習(xí)OpenCV,希望也能總結(jié)點(diǎn)東西。 一、DDB與DIB位圖 一個(gè)Windows的位圖實(shí)際上是一些和顯示像素相對(duì)應(yīng)的位陣列,它有兩種類(lèi)型:一種稱(chēng)之為GDI(Graphic Device Interface)位圖,另一種是DIB位圖(Device-Independent Bitmap)。 GDI位圖包含了一種和Windows的GDI模塊有關(guān)的Windows數(shù)據(jù)結(jié)構(gòu),該數(shù)據(jù)結(jié)構(gòu)是與設(shè)備有關(guān)的,故此位圖又稱(chēng)為DDB位圖(Device-Dependent Bitmap)。當(dāng)用戶(hù)的程序取得位圖數(shù)據(jù)信息時(shí),其位圖顯示方式視顯示卡而定。由于GDI位圖的這種設(shè)備依賴(lài)性,當(dāng)位圖通過(guò)網(wǎng)絡(luò)傳送到另一臺(tái)PC,很可能就會(huì)出現(xiàn)問(wèn)題。 DIB比GDI位圖有很多編程優(yōu)勢(shì),例如它自帶顏色信息,從而使調(diào)色板管理更加容易。且任何運(yùn)行Windows的機(jī)器都可以處理DIB,并通常以后綴為.BMP的文件形式被保存在磁盤(pán)中或作為資源存在于程序的EXE或DLL文件中。 二、CBitmap類(lèi)、BITMAP結(jié)構(gòu) CBitmap類(lèi)繼承自CGdiObject,是封裝了圖形設(shè)備接口(GDI)的位圖,提供成員函數(shù)來(lái)操縱位圖。要使用一個(gè)CBitmap對(duì)象,構(gòu)造該對(duì)象,用初始化成員函數(shù)之一把一個(gè)位圖句柄連接到該對(duì)象,然后調(diào)用該對(duì)象的成員函數(shù)。 CBitmap類(lèi)主要用于處理DDB位圖,封裝了與DDB位圖操作函數(shù)相關(guān)的數(shù)據(jù)結(jié)構(gòu)和操作函數(shù)。結(jié)構(gòu)體BITMAP定義了DDB位圖的類(lèi)型、寬度、高度、顏色和像素值,其定義如下: typedef struct _tagBITMAP??????? 而CBitmap的LoadBitmap、CreateCompatibleBitmap、SetBitmapBits、GetBitmap等成員函數(shù)則定義了對(duì)DDB位圖的裝載、創(chuàng)建、設(shè)定位值和屬性查詢(xún)等操作。 創(chuàng)建或裝入內(nèi)存的位圖必須用CDC::SelectObject函數(shù)來(lái)將其選入設(shè)備上下文中,然后用CDC的BitBlt或StretchBlt函數(shù)顯示出來(lái),這兩個(gè)函數(shù)的原型如下: BOOL BitBlt(int x, int y, int nWith, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop); 該函數(shù)把源設(shè)備上下文中的位圖復(fù)制到本身的設(shè)備上下文中,兩個(gè)設(shè)備下下文可以是內(nèi)存設(shè)備下下文,也可以是同一個(gè)設(shè)備上下文。 三、Image類(lèi)和Bitmap類(lèi) 在VC++.NET中,GDI+的Image類(lèi)封裝了對(duì)BMP、GIF、JPEG、PNG、TIFF、WMF(Windows元文件)和EMF(增強(qiáng)WMF)圖像文件的調(diào)入、顯示、格式轉(zhuǎn)換以及簡(jiǎn)單處理(如縮放、旋轉(zhuǎn)、拉伸等)的功能。而Bitmap類(lèi)(注意不是結(jié)構(gòu)BITMAP)是從Image類(lèi)繼承的一個(gè)圖像(另一個(gè)從Image繼承的類(lèi)是Metafile類(lèi)),它封裝了Windows位圖操作的常用功能。例如,Bitmap::SetPixel和Bitmap::GetPixel分別用來(lái)對(duì)位圖進(jìn)行讀寫(xiě)像素操作,從而可以為圖像的柔化和銳化處理提供一種可能。這些功能和MFC的新類(lèi)CImage功能基本一樣,如果僅用于圖像的讀取與顯示,用Bitmap類(lèi)或Image類(lèi)是不錯(cuò)的選擇,如果是做圖像處理,則CImage可能更符合MFC程序員的編程習(xí)慣。 四、CImage類(lèi) CImage類(lèi)是VC++.NET中MFC和ATL共享的新類(lèi),它能從外部磁盤(pán)中調(diào)入一個(gè)JPEG、GIF、BMP和PNG格式的圖像文件加以顯示,而且這些文件格式可以相互轉(zhuǎn)換。 CImage既能處理DIB位圖也能處理非DIB位圖,但你可以?xún)H用DIB位圖來(lái)Create或CImage::Load。你也可以使用Attach把一個(gè)非DIB位圖連接給CImage對(duì)象,但你不能使用下列方法,這些方法僅支持DIB位圖:GetBits、GetColorTable、GetMaxColorTable、Entries、GetPitch、GetPixelAddress、IsIndexed、SetColorTable。要確定一個(gè)連接的位圖是否是一個(gè)DIB位圖,調(diào)用IsDibSection。 由于CImage在不同的Windows操作系統(tǒng)中其某些性能是不一樣的,因此在使用時(shí)要特別注意。例如,CImage::PlgBlt和CImage::MaskBlt只能在 Windows NT 4.0 或更高版本中使用,但不能運(yùn)行在Windows 95/98 應(yīng)用程序中。CImage::AlphaBlend和CImage::TransparentBlt也只能在 Windows 2000/98或其更高版本中使用。即使在Windows 2000運(yùn)行程序還必須將stdafx.h文件中的WINVER和_WIN32_WINNT的預(yù)定義修改成0x0500才能正常使用。 CImage可以在MFC或ATL中使用。當(dāng)使用CImage創(chuàng)建一個(gè)項(xiàng)目時(shí),必須包含atlimage.h文件。 CImage封裝了DIB(設(shè)備無(wú)關(guān)位圖)的功能,因而可以讓我們能夠處理每個(gè)位圖像素。 CImage提供了HBITMAP操作符,因此HBITMAP為參數(shù)的地方,都可以用CImage來(lái)替代。 五、傳統(tǒng)的VC++中的圖像處理方法與VC++.NET中的圖像處理方法 由于DIB圖不依賴(lài)于具體設(shè)備,因此可以用來(lái)永久性地保存圖象。DIB一般是以*.BMP文件的形式保存在磁盤(pán)中的,有時(shí)也會(huì)保存在*.DIB文件中。運(yùn)行在不同輸出設(shè)備下的應(yīng)用程序可以通過(guò)DIB來(lái)交換圖象。因而在數(shù)字圖象處理中會(huì)經(jīng)常用到DIB位圖。DIB還可以用一種RLE算法來(lái)壓縮圖像數(shù)據(jù),但一般來(lái)說(shuō)DIB是不壓縮的。 在VC++.net之前MFC未提供現(xiàn)成的類(lèi)來(lái)封裝DIB,這給MFC用戶(hù)帶來(lái)很多不便。因?yàn)橛脩?hù)要想使用DIB,首先應(yīng)該了解DIB的結(jié)構(gòu)。 在內(nèi)存中,一個(gè)完整的DIB由兩部分組成:一個(gè)BITMAPINFO結(jié)構(gòu)和一個(gè)存儲(chǔ)像素陣列的數(shù)組。BITMAPINFO描述了位圖的大小,顏色模式和調(diào)色板等各種屬性,其定義為 typedef struct tagBITMAPINFO { RGBQUAD結(jié)構(gòu)用來(lái)描述顏色,其定義為 注意,RGBQUAD結(jié)構(gòu)中的顏色順序是BGR,而不是平常的RGB。 BITMAPINFOHEADER結(jié)構(gòu)包含了DIB的各種信息,其定義為 與DDB不同,DIB的字節(jié)數(shù)組是從圖象的最下面一行開(kāi)始的逐行向上存儲(chǔ)的,也即等于把圖象倒過(guò)來(lái)然后在逐行掃描。另外,字節(jié)數(shù)組中每個(gè)掃描行的字節(jié)數(shù)必需是4的倍數(shù),如果不足要用0補(bǔ)齊。 DIB可以存儲(chǔ)在*.BMP或*.DIB文件中。DIB文件是以BITMAPFILEHEADER結(jié)構(gòu)開(kāi)頭的,該結(jié)構(gòu)的定義為 緊隨該結(jié)構(gòu)的是一個(gè)BITMAPINFOHEADER結(jié)構(gòu),然后是RGBQUAD結(jié)構(gòu)組成的顏色表(如果有的話),文件最后存儲(chǔ)的是DIB的像素陣列。 DIB的顏色信息儲(chǔ)存在自己的顏色表中,程序一般要根據(jù)顏色表為DIB創(chuàng)建邏輯調(diào)色板。在輸出一幅DIB之前,程序應(yīng)該將其邏輯調(diào)色板選入到相關(guān)的設(shè)備上下文中并實(shí)現(xiàn)到系統(tǒng)調(diào)色板中,然后再調(diào)用相關(guān)的GDI函數(shù)(如::SetDIBitsToDevice或::StretchDIBits)輸出DIB。在輸出過(guò)程中,GDI函數(shù)會(huì)把DIB轉(zhuǎn)換成DDB,這項(xiàng)工作主要包括以下兩步:將DIB的顏色格式轉(zhuǎn)換成與輸出設(shè)備相同的顏色格式;將DIB像素的邏輯顏色索引轉(zhuǎn)換成系統(tǒng)調(diào)色板索引?!?/p> 看到這么多結(jié)構(gòu),你是不是已經(jīng)眼花繚亂了,然而更不幸的還在后面。以上說(shuō)的DIB是Windows中的DIB,還有一種DIB是OS/2 DIB,它和Windows DIB的主要區(qū)別是位圖信息結(jié)構(gòu)(信息頭和顏色表結(jié)構(gòu))。它們的圖像數(shù)據(jù)的存儲(chǔ)方式是完全一樣的。在OS/2 DIB中,與WIndows DIB的BITMAPFILEHEADER、BITMAPINFOHEADER、RGBQUAD相對(duì)應(yīng)的結(jié)構(gòu)分別是BITMAPCOREHEADER、BITMAPCOREINFO、和RGBTRIPLE。它們的定義分別如下: typedef struct tagBITMAPCOREHEADER // bmch??????? typedef struct tagBITMAPCOREINFO // bmci typedef struct tagRGBTRIPLE // rgbt??????? 因此再操作之前你應(yīng)該先根據(jù)BITMAPINFOHEADER的大小來(lái)判斷是哪一種DIB,然后再進(jìn)行操作。 由于MFC未提供一個(gè)封裝好的易用的DIB類(lèi),用戶(hù)在使用DIB時(shí)將面臨繁重的Windows API編程任務(wù)。不信你看看Microsoft提供的MFC的DibLook例程提就知道了。所以傳統(tǒng)的圖像處理方法一般都會(huì)把這些Win32 SDK中的操作DIB位圖的APIs做一個(gè)封裝,作為一個(gè)通用的類(lèi)來(lái)使用,以減少后續(xù)算法編寫(xiě)中的編程負(fù)擔(dān)。 VC++.NET提供了多種常用圖像文件格式(如BMP、TIF、GIF、JPEG與PNG等)的輸入/輸出模塊,ATL中的CImage類(lèi)極大地簡(jiǎn)化了圖像數(shù)據(jù)的操作,因此VC++.NET中的圖像處理應(yīng)以CImage為基礎(chǔ)。 |
轉(zhuǎn)載于:https://www.cnblogs.com/meiling/archive/2010/05/13/1734836.html
總結(jié)
以上是生活随笔為你收集整理的VC++和VC++.NET中与图像处理有关的几个概念、结构和类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Ext 与 Jquery 的结合应用
- 下一篇: 独立博客没有意义