国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
VC++和VC++.NET中與圖像處理有關(guān)的幾個概念、結(jié)構(gòu)和類

VC++和VC++.NET中與圖像處理有關(guān)的幾個概念、結(jié)構(gòu)和類

  最近一直在看VC++有關(guān)圖像處理方面的書,終于把以前一直混淆的幾個概念、結(jié)構(gòu)和類弄清楚了,特整理如下。如有錯誤,請大家批評指正,不勝感激。下一步想好好學習學習OpenCV,希望也能總結(jié)點東西。

一、DDB與DIB位圖

  一個Windows的位圖實際上是一些和顯示像素相對應(yī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)的,故此位圖又稱為DDB位圖(Device-Dependent Bitmap)。當用戶的程序取得位圖數(shù)據(jù)信息時,其位圖顯示方式視顯示卡而定。由于GDI位圖的這種設(shè)備依賴性,當位圖通過網(wǎng)絡(luò)傳送到另一臺PC,很可能就會出現(xiàn)問題。

  DIB比GDI位圖有很多編程優(yōu)勢,例如它自帶顏色信息,從而使調(diào)色板管理更加容易。且任何運行Windows的機器都可以處理DIB,并通常以后綴為.BMP的文件形式被保存在磁盤中或作為資源存在于程序的EXE或DLL文件中。

二、CBitmap類、BITMAP結(jié)構(gòu) 

  CBitmap類繼承自CGdiObject,是封裝了圖形設(shè)備接口(GDI)的位圖,提供成員函數(shù)來操縱位圖。要使用一個CBitmap對象,構(gòu)造該對象,用初始化成員函數(shù)之一把一個位圖句柄連接到該對象,然后調(diào)用該對象的成員函數(shù)。

  CBitmap類主要用于處理DDB位圖,封裝了與DDB位圖操作函數(shù)相關(guān)的數(shù)據(jù)結(jié)構(gòu)和操作函數(shù)。結(jié)構(gòu)體BITMAP定義了DDB位圖的類型、寬度、高度、顏色和像素值,其定義如下:

typedef struct _tagBITMAP       
{
  LONG          bmType ;                      // set to 0       
  LONG          bmWidth ;                     // width in pixels       
  LONG          bmHeight ;                   // height in pixels       
  LONG          bmWidthBytes ;                // width of row in bytes       
  WORD         bmPlanes ;                    // number of color planes       
  WORD         bmBitsPixel ;                 // number of bits per pixel       
  LPVOID       bmBits ;                             // pointer to pixel bits       
}       
BITMAP, * PBITMAP ;

  而CBitmap的LoadBitmap、CreateCompatibleBitmap、SetBitmapBits、GetBitmap等成員函數(shù)則定義了對DDB位圖的裝載、創(chuàng)建、設(shè)定位值和屬性查詢等操作。

  創(chuàng)建或裝入內(nèi)存的位圖必須用CDC::SelectObject函數(shù)來將其選入設(shè)備上下文中,然后用CDC的BitBlt或StretchBlt函數(shù)顯示出來,這兩個函數(shù)的原型如下:

BOOL BitBlt(int x, int y, int nWith, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop);

  該函數(shù)把源設(shè)備上下文中的位圖復(fù)制到本身的設(shè)備上下文中,兩個設(shè)備下下文可以是內(nèi)存設(shè)備下下文,也可以是同一個設(shè)備上下文。

三、Image類和Bitmap類

  在VC++.NET中,GDI+的Image類封裝了對BMP、GIF、JPEG、PNG、TIFF、WMF(Windows元文件)和EMF(增強WMF)圖像文件的調(diào)入、顯示、格式轉(zhuǎn)換以及簡單處理(如縮放、旋轉(zhuǎn)、拉伸等)的功能。Bitmap類(注意不是結(jié)構(gòu)BITMAP)是從Image類繼承的一個圖像(另一個從Image繼承的類是Metafile類),它封裝了Windows位圖操作的常用功能。例如,Bitmap::SetPixel和Bitmap::GetPixel分別用來對位圖進行讀寫像素操作,從而可以為圖像的柔化和銳化處理提供一種可能。這些功能和MFC的新類CImage功能基本一樣,如果僅用于圖像的讀取與顯示,用Bitmap類或Image類是不錯的選擇,如果是做圖像處理,則CImage可能更符合MFC程序員的編程習慣。

四、CImage類

  CImage類是VC++.NET中MFC和ATL共享的新類,它能從外部磁盤中調(diào)入一個JPEG、GIF、BMP和PNG格式的圖像文件加以顯示,而且這些文件格式可以相互轉(zhuǎn)換。

  CImage既能處理DIB位圖也能處理非DIB位圖,但你可以僅用DIB位圖來Create或CImage::Load。你也可以使用Attach把一個非DIB位圖連接給CImage對象,但你不能使用下列方法,這些方法僅支持DIB位圖:GetBits、GetColorTable、GetMaxColorTable、Entries、GetPitch、GetPixelAddress、IsIndexed、SetColorTable。要確定一個連接的位圖是否是一個DIB位圖,調(diào)用IsDibSection。

  由于CImage在不同的Windows操作系統(tǒng)中其某些性能是不一樣的,因此在使用時要特別注意。例如,CImage::PlgBlt和CImage::MaskBlt只能在 Windows NT 4.0 或更高版本中使用,但不能運行在Windows 95/98 應(yīng)用程序中。CImage::AlphaBlend和CImage::TransparentBlt也只能在 Windows 2000/98或其更高版本中使用。即使在Windows 2000運行程序還必須將stdafx.h文件中的WINVER和_WIN32_WINNT的預(yù)定義修改成0x0500才能正常使用。 CImage可以在MFC或ATL中使用。當使用CImage創(chuàng)建一個項目時,必須包含atlimage.h文件。

  CImage封裝了DIB(設(shè)備無關(guān)位圖)的功能,因而可以讓我們能夠處理每個位圖像素。

  CImage提供了HBITMAP操作符,因此HBITMAP為參數(shù)的地方,都可以用CImage來替代。

五、傳統(tǒng)的VC++中的圖像處理方法與VC++.NET中的圖像處理方法

  由于DIB圖不依賴于具體設(shè)備,因此可以用來永久性地保存圖象。DIB一般是以*.BMP文件的形式保存在磁盤中的,有時也會保存在*.DIB文件中。運行在不同輸出設(shè)備下的應(yīng)用程序可以通過DIB來交換圖象。因而在數(shù)字圖象處理中會經(jīng)常用到DIB位圖。DIB還可以用一種RLE算法來壓縮圖像數(shù)據(jù),但一般來說DIB是不壓縮的。

  在VC++.net之前MFC未提供現(xiàn)成的類來封裝DIB,這給MFC用戶帶來很多不便。因為用戶要想使用DIB,首先應(yīng)該了解DIB的結(jié)構(gòu)。

  在內(nèi)存中,一個完整的DIB由兩部分組成:一個BITMAPINFO結(jié)構(gòu)和一個存儲像素陣列的數(shù)組。BITMAPINFO描述了位圖的大小,顏色模式和調(diào)色板等各種屬性,其定義為 typedef struct tagBITMAPINFO { 
    BITMAPINFOHEADER bmiHeader; 
    RGBQUAD bmiColors[1]; //顏色表
} BITMAPINFO;

RGBQUAD結(jié)構(gòu)用來描述顏色,其定義為
typedef struct tagRGBQUAD {
  BYTE     rgbBlue; //藍色的強度
  BYTE     rgbGreen; //綠色的強度
  BYTE     rgbRed; //紅色的強度
  BYTE     rgbReserved; //保留字節(jié),為0
} RGBQUAD;

注意,RGBQUAD結(jié)構(gòu)中的顏色順序是BGR,而不是平常的RGB。

BITMAPINFOHEADER結(jié)構(gòu)包含了DIB的各種信息,其定義為
typedef struct tagBITMAPINFOHEADER{
  DWORD     biSize; //該結(jié)構(gòu)的大小
  LONG     biWidth; //位圖的寬度(以像素為單位)
  LONG     biHeight; //位圖的高度(以像素為單位)
  WORD     biPlanes; //必須為1
  WORD     biBitCount //每個像素的位數(shù)(1、4、8、16、24或32)
  DWORD     biCompression; //壓縮方式,一般為0或BI_RGB (未壓縮)
  DWORD     biSizeImage; //以字節(jié)為單位的圖象大小(僅用于壓縮位圖)
  LONG     biXPelsPerMeter; //以目標設(shè)備每米的像素數(shù)來說明位圖的水平分辨率
  LONG     biYPelsPerMeter; //以目標設(shè)備每米的像素數(shù)來說明位圖的垂直分辨率
  DWORD     biClrUsed; /*顏色表的顏色數(shù),若為0則位圖使用由biBitCount指定的最大顏色數(shù)*/
  DWORD     biClrImportant; //重要顏色的數(shù)目,若該值為0則所有顏色都重要
} BITMAPINFOHEADER;

  與DDB不同,DIB的字節(jié)數(shù)組是從圖象的最下面一行開始的逐行向上存儲的,也即等于把圖象倒過來然后在逐行掃描。另外,字節(jié)數(shù)組中每個掃描行的字節(jié)數(shù)必需是4的倍數(shù),如果不足要用0補齊。

DIB可以存儲在*.BMP或*.DIB文件中。DIB文件是以BITMAPFILEHEADER結(jié)構(gòu)開頭的,該結(jié)構(gòu)的定義為
typedef struct tagBITMAPFILEHEADER {
  WORD     bfType; //文件類型,必須為“BM”
  DWORD     bfSize; //文件的大小
  WORD     bfReserved1; //為0
  WORD     bfReserved2; //為0
  DWORD     bfOffBits; //存儲的像素陣列相對于文件頭的偏移量
} BITMAPFILEHEADER;

  緊隨該結(jié)構(gòu)的是一個BITMAPINFOHEADER結(jié)構(gòu),然后是RGBQUAD結(jié)構(gòu)組成的顏色表(如果有的話),文件最后存儲的是DIB的像素陣列。

  DIB的顏色信息儲存在自己的顏色表中,程序一般要根據(jù)顏色表為DIB創(chuàng)建邏輯調(diào)色板。在輸出一幅DIB之前,程序應(yīng)該將其邏輯調(diào)色板選入到相關(guān)的設(shè)備上下文中并實現(xiàn)到系統(tǒng)調(diào)色板中,然后再調(diào)用相關(guān)的GDI函數(shù)(如::SetDIBitsToDevice或::StretchDIBits)輸出DIB。在輸出過程中,GDI函數(shù)會把DIB轉(zhuǎn)換成DDB,這項工作主要包括以下兩步:將DIB的顏色格式轉(zhuǎn)換成與輸出設(shè)備相同的顏色格式;將DIB像素的邏輯顏色索引轉(zhuǎn)換成系統(tǒng)調(diào)色板索引?!?

  看到這么多結(jié)構(gòu),你是不是已經(jīng)眼花繚亂了,然而更不幸的還在后面。以上說的DIB是Windows中的DIB,還有一種DIB是OS/2 DIB,它和Windows DIB的主要區(qū)別是位圖信息結(jié)構(gòu)(信息頭和顏色表結(jié)構(gòu))。它們的圖像數(shù)據(jù)的存儲方式是完全一樣的。在OS/2 DIB中,與WIndows DIB的BITMAPFILEHEADER、BITMAPINFOHEADER、RGBQUAD相對應(yīng)的結(jié)構(gòu)分別是BITMAPCOREHEADER、BITMAPCOREINFO、和RGBTRIPLE。它們的定義分別如下:

typedef struct tagBITMAPCOREHEADER  // bmch       
{       
  DWORD         bcSize ;              // size of the structure = 12       
  WORD          bcWidth ;             // width of image in pixels       
  WORD          bcHeight ;           // height of image in pixels       
  WORD          bcPlanes ;            // = 1       
  WORD          bcBitCount ;          // bits per pixel (1, 4, 8, or 24)       
}       
BITMAPCOREHEADER, * PBITMAPCOREHEADER ;

typedef struct tagBITMAPCOREINFO  // bmci
{       
  BITMAPCOREHEADER      bmciHeader ;                  // core-header structure       
  RGBTRIPLE             bmciColors[1] ;               // color table array       
}       
BITMAPCOREINFO, * PBITMAPCOREINFO ;

typedef struct tagRGBTRIPLE  // rgbt       
{       
  BYTE     rgbtBlue ;       // blue level       
  BYTE     rgbtGreen ;      // green level       
  BYTE     rgbtRed ;        // red level       
}       
RGBTRIPLE;

  因此再操作之前你應(yīng)該先根據(jù)BITMAPINFOHEADER的大小來判斷是哪一種DIB,然后再進行操作。

  由于MFC未提供一個封裝好的易用的DIB類,用戶在使用DIB時將面臨繁重的Windows API編程任務(wù)。不信你看看Microsoft提供的MFC的DibLook例程提就知道了。所以傳統(tǒng)的圖像處理方法一般都會把這些Win32 SDK中的操作DIB位圖的APIs做一個封裝,作為一個通用的類來使用,以減少后續(xù)算法編寫中的編程負擔。

  VC++.NET提供了多種常用圖像文件格式(如BMP、TIF、GIF、JPEG與PNG等)的輸入/輸出模塊,ATL中的CImage類極大地簡化了圖像數(shù)據(jù)的操作,因此VC++.NET中的圖像處理應(yīng)以CImage為基礎(chǔ)。
  現(xiàn)在市面上有一些冠名教用VC++.NET做圖像處理的書,但是編程方法還是老的一套,沒有跳出設(shè)備相關(guān)位圖(DDB)與設(shè)備無關(guān)位圖(DIB)概念的條框,編程方法比較復(fù)雜、繁瑣、低效。用VC++.NET環(huán)境做圖像處理,應(yīng)該以CImage類為基礎(chǔ),完全跳出DDB、DIB概念的條框,才能使得處理方法返樸歸真,大為簡化

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
vc 位圖操作 BITMAPINFO 賦值
hook 驅(qū)動 截屏
Visual C++中DDB與DIB位圖編程全攻略
BMP
Visual C++中DDB與DIB位圖編程全攻略 (2)
VC2005 GDI 編程
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服