實(shí)驗(yàn)一位圖文件的讀取與顯示_第1頁
實(shí)驗(yàn)一位圖文件的讀取與顯示_第2頁
實(shí)驗(yàn)一位圖文件的讀取與顯示_第3頁
實(shí)驗(yàn)一位圖文件的讀取與顯示_第4頁
實(shí)驗(yàn)一位圖文件的讀取與顯示_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、實(shí)驗(yàn)一 位圖文件的讀取與顯示一、實(shí)驗(yàn)背景1 位圖文件格式說明位圖文件格式由四部分組成,如圖 1所示,分別是位圖文件頭、位圖信息頭、調(diào)色板以及位圖像素?cái)?shù)據(jù),其中調(diào)色板信息為可選信息,只有當(dāng)每個(gè)像素的比特?cái)?shù)小于或等于8(BITMAPINFOHEADER.biBitCount<=8)時(shí)才存在,即為一個(gè)顏色查找表。需要注意的是,位圖文件存儲(chǔ)時(shí)為了提高內(nèi)存訪問的速度,每一行的字節(jié)數(shù)必須是4的倍數(shù),即:如果一幅圖像的寬度為253,每個(gè)像素用8bit表示,因此,該圖像實(shí)際每行所占的存儲(chǔ)空間數(shù)為253Byte,但為了與4對(duì)齊,存儲(chǔ)時(shí)所用的存儲(chǔ)空間為256Byte。具體而言,假設(shè)圖像的寬度為w,每個(gè)像素用

2、n比特表示,則圖像每行像素所占的字節(jié)數(shù)為:(w * n + 31)/32 * 4圖 1 位圖文件格式說明2 位圖文件讀取位圖文件的讀取包括兩步:(1)根據(jù)第1節(jié)中的位圖文件格式說明,對(duì)位圖文件進(jìn)行解析;(2)根據(jù)讀取的內(nèi)容創(chuàng)建可供顯示的位圖句柄。 (1)位圖文件解析 /open fileFILE *fp = NULL;fopen_s(&fp, strPath, _T("rb");if (fp = NULL)CString str = _T("File not exist: " )+ strPath;AfxMessageBox(str);retur

3、n NULL;/bitmap file headerBITMAPFILEHEADER bmFileHeader;fread(&bmFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);if (bmFileHeader.bfType != 0x4d42)AfxMessageBox(_T("file type is not bitmap");return NULL;/bitmap info headerBITMAPINFO bmInfo;BITMAPINFOHEADER &bmInfoHeader = bmInfo.bmiHe

4、ader;fread(&bmInfoHeader, sizeof(BITMAPINFOHEADER), 1, fp);if (bmInfoHeader.biSize != sizeof(BITMAPINFOHEADER)AfxMessageBox(_T("size of bitmap info header is inconsistent");return NULL;/whether is compressedif (bmInfoHeader.biCompression != BI_RGB)AfxMessageBox(_T("File is compres

5、sed");return NULL;int nPalettes = bmInfoHeader.biClrUsed;if (nPalettes = 0 && bmInfoHeader.biBitCount <= 8)nPalettes = 1 << bmInfoHeader.biBitCount;if (bmFileHeader.bfOffBits != sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nPalettes * sizeof(RGBQUAD)AfxMessageBox(_T(&q

6、uot;off bits is inconsistent");return NULL;/Palette/RGBQUAD *pPalette = NULL;byte *pBmInfo = NULL;if (nPalettes > 0)pBmInfo = new bytesizeof(BITMAPINFOHEADER) + nPalettes * sizeof(RGBQUAD);memcpy(pBmInfo, &bmInfoHeader, sizeof(BITMAPINFOHEADER);byte *pPalette = pBmInfo + sizeof(BITMAPINF

7、OHEADER);fread(pPalette, sizeof(RGBQUAD), nPalettes, fp);/line widthint nLineByte = (bmInfoHeader.biWidth * bmInfoHeader.biBitCount + 31) / 32 * 4;/不直接使用bmInfoHeader.biSizeImage,因?yàn)閳D像不壓縮時(shí)該字段可以為零int nImageBytes = nLineByte * bmInfoHeader.biHeight;/image databyte *pContents = new bytenImageBytes;fread(

8、pContents, nImageBytes, 1, fp);(2)將讀取的內(nèi)容轉(zhuǎn)換為Bitmap句柄該步驟需使用系統(tǒng)函數(shù)CreateDIBitmap。CreateDIBitmap的函數(shù)說明如下:HBITMAP CreateDIBitmap(HDC hdc, CONST BITMAPINFOHEADER *lpbmih, DWORD fdwlnit, CONST VOID *lpblnit, CONST BITMAPINFO *lpbmi, UINT fuUsage);參數(shù):hdc:設(shè)備環(huán)境句柄。lpbmih:指向位圖信息頭結(jié)構(gòu)的指針,它可以是下列操作系統(tǒng)位圖信息頭之一:Fdwlnit:位標(biāo)識(shí)

9、集。它指定系統(tǒng)如何對(duì)位圖的位進(jìn)行初始化。CBM_INIT:如果設(shè)置了該標(biāo)志,那么系統(tǒng)將使用lpblnit和lpbmi兩個(gè)參數(shù)指向的數(shù)據(jù) 來對(duì)位圖中的位進(jìn)行初始化。如果沒有該標(biāo)志,那么表示上述兩個(gè)參數(shù)指向的數(shù)據(jù)無效。如果fdwlnit為0,那么系統(tǒng)不會(huì)對(duì)位圖的位進(jìn)行初始化。lpblnit:該指針指向包含初始的位圖數(shù)據(jù)的字節(jié)類型數(shù)組。數(shù)據(jù)格式與參數(shù)lpbmi指向的BITMAPINFO結(jié)構(gòu)中的成員biBitCount有關(guān)。lpbmi:指向BITMAPINFO結(jié)構(gòu)的旨針。該結(jié)構(gòu)描述了參數(shù)lpbmi指向的數(shù)組的維數(shù)和顏色格式。fuUsage:表示BITMAPINFO結(jié)構(gòu)的成員bmiColors是否初始化

10、過,并且如果是,那么bmiColors是否包含明確的紅、綠、藍(lán)(RGB)值或調(diào)色板索引。參數(shù)fuUsage必須取下列值中的一個(gè),這些值的含義為:DIB_PAL_COLORS:表示提供一個(gè)顏色表,并且該表由該位圖要選入的設(shè)備環(huán)境的邏輯調(diào)色板的16位索引值數(shù)組組成。DIB_RGB_COLORS:表示提供一個(gè)顏色表,并且表中包含了原義的RGB值。 if (pBmInfo = NULL)/無調(diào)色板時(shí),BITMAPINFO就等同于BITMAPINFOHEADERpBmInfo = (byte *)&bmInfo;/create DIB BitmapHDC hdc = GetDC(AfxGetMa

11、inWnd()->GetSafeHwnd();HBITMAP hBitmap = CreateDIBitmap(hdc, &bmInfoHeader, CBM_INIT, pContents, (BITMAPINFO *)pBmInfo, DIB_RGB_COLORS);delete pContents;if (nPalettes > 0)delete pBmInfo;3 位圖的顯示位圖的顯示分為三步:(1)利用CreateCompatibleDC()函數(shù)創(chuàng)建兼容內(nèi)存設(shè)備環(huán)境;(2)利用SelectObject()函數(shù)將位圖對(duì)象放入兼容內(nèi)存設(shè)備環(huán)境;(3)使用BitBlt(

12、)函數(shù)或者StrechBlt()函數(shù)將位圖顯示在屏幕上。BitBlt()只能按照位圖原來的大小進(jìn)行顯示,而StrechBlt()可以對(duì)位圖進(jìn)行放大或縮小。CDC compDC;compDC.CreateCompatibleDC(pDC); /創(chuàng)建pDC兼容的設(shè)備環(huán)境compDC.SelectObject(pBitmap); /將位圖對(duì)象放入兼容設(shè)備環(huán)境/顯示位圖BITMAP bitmap;pBitmap->GetBitmap(&bitmap); /獲取位圖信息pDC->BitBlt(0, 0, /位圖顯示位置bitmap.bmWidth, bitmap.bmHeight,

13、/顯示位圖的寬度和高度&compDC, /位圖所在兼容DC0, 0, /兼容DC中的位置SRCCOPY); /顯示方式二、主要問題在Windows環(huán)境下,通過解析位圖文件的格式,讀入位圖并進(jìn)行顯示,不能使用Windows中已有的API(如LoadImage函數(shù))讀取位圖文件,即自己實(shí)現(xiàn)LoadImage函數(shù)的功能:LoadImage(NULL, “l(fā)enna.bmp”, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)3、 采取的解決方法1、 生成一名為Bitmap的基于MFC的應(yīng)用程序框架: 選擇“文件”菜單“新建”選項(xiàng),在打開的窗口中選擇“工程”選項(xiàng),選中M

14、FC AppWizard(exe)。并在“工程名稱”中輸入Bitmap ,選擇存放“工程”的位置。如下圖所示: 選擇確定,進(jìn)入下一步。選擇“單文檔”,并在最后CdipView類的基類中選擇CscrollView,使應(yīng)用程序視圖具有滾動(dòng)條。2、在應(yīng)用程序中加入具體的函數(shù)和變量。 如上圖所示,在FileView中,選擇頭文件中的BitmapView.h文件并打開,添加如下列的公共變量:public:  int m_x;  HBITMAP m_Bmp;     

15、  LPVOID m_ColorList;  LPBYTE m_Image;     LPBITMAPINFOHEADER m_DibHead;   enum allocate None, crtallocate, heapallocate;  allocate m_nBmpallocate;  allocate m_nImageallocate;

16、  DWORD m_ImageSize;   int m_nPalette;  HANDLE m_hFile;  HANDLE m_hMap;  LPVOID m_lpvFile;  HPALETTE m_hPalette;  HGLOBAL m_hGlob;  在Class View中選擇CGsmView單擊右鍵選擇添加成員函數(shù),把下列函數(shù)加入到C+Vie

17、w類中  void SetPaletteSize(int nBitCount);  void Clear();  BOOL ReadFile(CFile *pFile);  BOOL SetPalette();  BOOL GetPalette(); BOOL DibToDC(CDC* pDC,CSize size);  BOOL MemToDib(LPVO

18、ID lmem);  CSize GetDibSize(); 3、 把對(duì)應(yīng)函數(shù)代碼拷貝到新的函數(shù)中;void CBitmapView:SetPaletteSize(int nBitCount)if(m_DibHead->biSize!=sizeof(BITMAPINFOHEADER) throw new CException; m_ImageSize=m_DibHead->biSizeImage;if(m_ImageSize=0)DWORD dwBytes=(DWORD)m_DibHead->biWidth*m_DibHead

19、->biBitCount)/32;if(DWORD)m_DibHead->biWidth*m_DibHead->biBitCount)%32)dwBytes+; dwBytes*=4;m_ImageSize=dwBytes*m_DibHead->biHeight;m_ColorList=(LPBYTE)m_DibHead+sizeof(BITMAPINFOHEADER);if(m_DibHead=NULL)|(m_DibHead->biClrUsed=0)switch(nBitCount)case 1:m_nPalette=2;break;case 4:m_nPa

20、lette=16;break;case 8:m_nPalette=256;break;case 16:case 24:case 32:m_nPalette=0;break;default:ASSERT(FALSE);else m_nPalette=m_DibHead->biClrUsed; ASSERT(m_nPalette>=0)&&(m_nPalette<=256);void CBitmapView:Clear()if(m_hFile=NULL) return;:UnmapViewOfFile(m_lpvFile);:CloseHandle(m_hMap)

21、;:CloseHandle(m_hFile);m_hFile=NULL; if(m_nBmpallocate=crtallocate) delete m_DibHead; else if(m_nBmpallocate=heapallocate) :GlobalUnlock(m_hGlob); :GlobalFree(m_hGlob); if(m_nImageallocate=crtallocate) delete m_Image; if(m_hPalette!=NULL) :DeleteObject(m_hPalette); if(m_Bmp!=NULL) :DeleteObject(m_Bm

22、p); m_nBmpallocate=m_nImageallocate=None; m_hGlob=NULL; m_DibHead=NULL; m_Image=NULL; m_ColorList=NULL; m_nPalette=0; m_ImageSize=0; m_lpvFile=NULL; m_hMap=NULL; m_hFile=NULL; m_Bmp=NULL; m_hPalette=NULL;BOOL CBitmapView:ReadFile(CFile *pFile)int nCount,nSize;BITMAPFILEHEADER bmfh;Clear();try nCount

23、=pFile->Read(LPVOID)&bmfh,sizeof(BITMAPFILEHEADER); if(nCount!=sizeof(BITMAPFILEHEADER) throw new CException; if(bmfh.bfType!=0x4d42) throw new CException; nSize=bmfh.bfOffBits-sizeof(BITMAPFILEHEADER); m_DibHead=(LPBITMAPINFOHEADER) new charnSize; m_nBmpallocate=m_nImageallocate=crtallocate;

24、 nCount=pFile->Read(m_DibHead,nSize); SetPaletteSize(m_DibHead->biBitCount); GetPalette(); m_Image=(LPBYTE) new charm_ImageSize; nCount=pFile->Read(m_Image,m_ImageSize); catch(CException* tmpc)AfxMessageBox("文件讀取錯(cuò)誤");tmpc->Delete();return FALSE; return TRUE;BOOL CBitmapView:Set

25、Palette()if(m_nPalette!=0)return FALSE;CClientDC dc(this);CDC *pDC=&dc;m_hPalette=:CreateHalftonePalette(pDC->GetSafeHdc();return TRUE;BOOL CBitmapView:GetPalette()if(m_nPalette=0)return FALSE;if(m_hPalette!=NULL):DeleteObject(m_hPalette);LPLOGPALETTE pTempPalette=(LPLOGPALETTE) new char2*siz

26、eof(WORD)+m_nPalette*sizeof(PALETTEENTRY);pTempPalette->palVersion=0x30;pTempPalette->palNumEntries=m_nPalette;LPRGBQUAD pRGBQuad=(LPRGBQUAD)m_ColorList;for(int i=0;i<m_nPalette;i+)pTempPalette->palPalEntryi.peRed=pRGBQuad->rgbRed;pTempPalette->palPalEntryi.peGreen=pRGBQuad->rgb

27、Green;pTempPalette->palPalEntryi.peBlue=pRGBQuad->rgbBlue;pTempPalette->palPalEntryi.peFlags=0;pRGBQuad+;m_hPalette=:CreatePalette(pTempPalette);delete pTempPalette;return TRUE;BOOL CBitmapView:DibToDC(CDC *pDC, CSize size)if(m_DibHead=NULL)return FALSE;if(m_hPalette!=NULL)HDC hdc=pDC->G

28、etSafeHdc();:SelectPalette(hdc,m_hPalette,TRUE);pDC->SetStretchBltMode(COLORONCOLOR);:StretchDIBits(pDC->GetSafeHdc(),0,0,size.cx,size.cy,0,0,m_DibHead->biWidth,m_DibHead->biHeight,m_Image,(LPBITMAPINFO)m_DibHead,DIB_RGB_COLORS,SRCCOPY);return TRUE;BOOL CBitmapView:MemToDib(LPVOID lmem)C

29、lear();m_DibHead=(LPBITMAPINFOHEADER)lmem;SetPaletteSize(m_DibHead->biBitCount);m_Image=(LPBYTE)m_ColorList+sizeof(RGBQUAD)*m_nPalette;GetPalette();return TRUE;CSize CBitmapView:GetDibSize()if(m_DibHead=NULL)return CSize(0,0);return CSize(int)m_DibHead->biWidth,(int)m_DibHead->biHeight);4、編

30、譯檢驗(yàn)沒有出現(xiàn)錯(cuò)誤; 出現(xiàn)顯示位圖的菜單框Bitmap,結(jié)果如下:5、  在程序資源中創(chuàng)建位圖條為默認(rèn);經(jīng)查資料,在這里簡(jiǎn)單介紹一下如何建立一個(gè)位圖資源。新建一個(gè)VC+工程,取名為“Bitmap”,具體的步驟參考菜單實(shí)例中的工程創(chuàng)建,創(chuàng)建好后,單擊主菜單中的“插入”“資源”,彈出“插入資源”對(duì)話框?;蛘邌螕繇?xiàng)目工作區(qū)中的“Resource View”標(biāo)簽,激活資源視圖選項(xiàng)卡,然后選中其中任一節(jié)點(diǎn)右鍵單擊,在快捷菜單中選擇“插入”命令,會(huì)彈出相同的資源對(duì)話框。在“插入資源”對(duì)話框中選擇Bitmap,單擊右邊的“新建”按鈕新建一個(gè)位圖資源,其ID為IDB_BITMAP1(或者單

31、擊“引入”按鈕,從文件中導(dǎo)入一個(gè)位圖資源),如圖下圖所示:在項(xiàng)目工作區(qū)中的“Resource View”標(biāo)簽下,點(diǎn)鼠標(biāo)右鍵選擇Bitmap下的“IDB_BITMAP1”,選擇“屬性”命令,彈出屬性對(duì)話框,如下圖所示。在其中,對(duì)諸如ID、File name等屬性取默認(rèn)值?!拔粓D屬性”對(duì)話框在項(xiàng)目工作區(qū)中的“Resource View”標(biāo)簽下,雙擊Bitmap下的“IDB_BITMAP1”,在彈出的文件測(cè)覽窗口中出現(xiàn)位圖資源編輯器,如下圖所示。在該編輯區(qū)里可以完成與畫圖程序同樣的各種編輯功能,包括填充各種形狀,擦去錯(cuò)誤等,可在其中繪制期望的位圖。位圖資源編輯器繪制好位圖后,單擊“文件”“保存”命令

32、保存資源文件。這樣,一個(gè)位圖資源就制作好了。在程序中,可利用CBitmap類的LoadBitmap函數(shù)來加載位圖資源。6、 修改OnInitialUpdate函數(shù)中的代碼; void CBitmapView:OnInitialUpdate()CScrollView:OnInitialUpdate();CSize sizeTotal;/ TODO: calculate the total size of this viewm_x=25;CSize MaxSize(24000,32000);CSize MinSize(MaxSize.cx/100,MaxSize.cy/100);SetScrollSizes(MM_HIMETRIC,MaxSize,MaxSize,MinSize);LPVOID lFirstBMP=(LPVOID):LoadResource(NULL,:FindResource(NULL,MAKEINTRESOURCE(IDB_BITMAP1),RT_BITMAP);MemToDib(lFirstBMP); 7、 修改OnDraw函數(shù)中的代碼;  void CBitmapView:OnDraw(CDC* pDC)CBitmapDoc* pDoc = GetDocument()

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論