版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、實驗一 位圖文件的讀取與顯示一、實驗背景1 位圖文件格式說明位圖文件格式由四部分組成,如圖 1所示,分別是位圖文件頭、位圖信息頭、調色板以及位圖像素數(shù)據(jù),其中調色板信息為可選信息,只有當每個像素的比特數(shù)小于或等于8(BITMAPINFOHEADER.biBitCount<=8)時才存在,即為一個顏色查找表。需要注意的是,位圖文件存儲時為了提高內(nèi)存訪問的速度,每一行的字節(jié)數(shù)必須是4的倍數(shù),即:如果一幅圖像的寬度為253,每個像素用8bit表示,因此,該圖像實際每行所占的存儲空間數(shù)為253Byte,但為了與4對齊,存儲時所用的存儲空間為256Byte。具體而言,假設圖像的寬度為w,每個像素用
2、n比特表示,則圖像每行像素所占的字節(jié)數(shù)為:(w * n + 31)/32 * 4圖 1 位圖文件格式說明2 位圖文件讀取位圖文件的讀取包括兩步:(1)根據(jù)第1節(jié)中的位圖文件格式說明,對位圖文件進行解析;(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,因為圖像不壓縮時該字段可以為零int nImageBytes = nLineByte * bmInfoHeader.biHeight;/image databyte *pContents = new bytenImageBytes;fread(
8、pContents, nImageBytes, 1, fp);(2)將讀取的內(nèi)容轉換為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:設備環(huán)境句柄。lpbmih:指向位圖信息頭結構的指針,它可以是下列操作系統(tǒng)位圖信息頭之一:Fdwlnit:位標識
9、集。它指定系統(tǒng)如何對位圖的位進行初始化。CBM_INIT:如果設置了該標志,那么系統(tǒng)將使用lpblnit和lpbmi兩個參數(shù)指向的數(shù)據(jù) 來對位圖中的位進行初始化。如果沒有該標志,那么表示上述兩個參數(shù)指向的數(shù)據(jù)無效。如果fdwlnit為0,那么系統(tǒng)不會對位圖的位進行初始化。lpblnit:該指針指向包含初始的位圖數(shù)據(jù)的字節(jié)類型數(shù)組。數(shù)據(jù)格式與參數(shù)lpbmi指向的BITMAPINFO結構中的成員biBitCount有關。lpbmi:指向BITMAPINFO結構的旨針。該結構描述了參數(shù)lpbmi指向的數(shù)組的維數(shù)和顏色格式。fuUsage:表示BITMAPINFO結構的成員bmiColors是否初始化
10、過,并且如果是,那么bmiColors是否包含明確的紅、綠、藍(RGB)值或調色板索引。參數(shù)fuUsage必須取下列值中的一個,這些值的含義為:DIB_PAL_COLORS:表示提供一個顏色表,并且該表由該位圖要選入的設備環(huán)境的邏輯調色板的16位索引值數(shù)組組成。DIB_RGB_COLORS:表示提供一個顏色表,并且表中包含了原義的RGB值。 if (pBmInfo = NULL)/無調色板時,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)存設備環(huán)境;(2)利用SelectObject()函數(shù)將位圖對象放入兼容內(nèi)存設備環(huán)境;(3)使用BitBlt(
12、)函數(shù)或者StrechBlt()函數(shù)將位圖顯示在屏幕上。BitBlt()只能按照位圖原來的大小進行顯示,而StrechBlt()可以對位圖進行放大或縮小。CDC compDC;compDC.CreateCompatibleDC(pDC); /創(chuàng)建pDC兼容的設備環(huán)境compDC.SelectObject(pBitmap); /將位圖對象放入兼容設備環(huán)境/顯示位圖BITMAP bitmap;pBitmap->GetBitmap(&bitmap); /獲取位圖信息pDC->BitBlt(0, 0, /位圖顯示位置bitmap.bmWidth, bitmap.bmHeight,
13、/顯示位圖的寬度和高度&compDC, /位圖所在兼容DC0, 0, /兼容DC中的位置SRCCOPY); /顯示方式二、主要問題在Windows環(huán)境下,通過解析位圖文件的格式,讀入位圖并進行顯示,不能使用Windows中已有的API(如LoadImage函數(shù))讀取位圖文件,即自己實現(xiàn)LoadImage函數(shù)的功能:LoadImage(NULL, “l(fā)enna.bmp”, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)3、 采取的解決方法1、 生成一名為Bitmap的基于MFC的應用程序框架: 選擇“文件”菜單“新建”選項,在打開的窗口中選擇“工程”選項,選中M
14、FC AppWizard(exe)。并在“工程名稱”中輸入Bitmap ,選擇存放“工程”的位置。如下圖所示: 選擇確定,進入下一步。選擇“單文檔”,并在最后CdipView類的基類中選擇CscrollView,使應用程序視圖具有滾動條。2、在應用程序中加入具體的函數(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、 把對應函數(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("文件讀取錯誤");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、譯檢驗沒有出現(xiàn)錯誤; 出現(xiàn)顯示位圖的菜單框Bitmap,結果如下:5、 在程序資源中創(chuàng)建位圖條為默認;經(jīng)查資料,在這里簡單介紹一下如何建立一個位圖資源。新建一個VC+工程,取名為“Bitmap”,具體的步驟參考菜單實例中的工程創(chuàng)建,創(chuàng)建好后,單擊主菜單中的“插入”“資源”,彈出“插入資源”對話框?;蛘邌螕繇椖抗ぷ鲄^(qū)中的“Resource View”標簽,激活資源視圖選項卡,然后選中其中任一節(jié)點右鍵單擊,在快捷菜單中選擇“插入”命令,會彈出相同的資源對話框。在“插入資源”對話框中選擇Bitmap,單擊右邊的“新建”按鈕新建一個位圖資源,其ID為IDB_BITMAP1(或者單
31、擊“引入”按鈕,從文件中導入一個位圖資源),如圖下圖所示:在項目工作區(qū)中的“Resource View”標簽下,點鼠標右鍵選擇Bitmap下的“IDB_BITMAP1”,選擇“屬性”命令,彈出屬性對話框,如下圖所示。在其中,對諸如ID、File name等屬性取默認值。“位圖屬性”對話框在項目工作區(qū)中的“Resource View”標簽下,雙擊Bitmap下的“IDB_BITMAP1”,在彈出的文件測覽窗口中出現(xiàn)位圖資源編輯器,如下圖所示。在該編輯區(qū)里可以完成與畫圖程序同樣的各種編輯功能,包括填充各種形狀,擦去錯誤等,可在其中繪制期望的位圖。位圖資源編輯器繪制好位圖后,單擊“文件”“保存”命令
32、保存資源文件。這樣,一個位圖資源就制作好了。在程序中,可利用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等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025版市政基礎設施文明施工與環(huán)境保護責任協(xié)議3篇
- 2025年陜西燃氣集團工程有限公司招聘筆試參考題庫含答案解析
- 2025年度個人門面房出租合同(含家具配置及經(jīng)營指導協(xié)議)4篇
- 2025年度個人信用卡透支擔保合同協(xié)議書4篇
- 2025年度個人醫(yī)療健康保險繳費協(xié)議書4篇
- 2025年全球及中國智能直播一體機行業(yè)頭部企業(yè)市場占有率及排名調研報告
- 2024年六五環(huán)境日網(wǎng)絡知識競賽測試題庫及答案
- 設計合同協(xié)議書
- 2025年度個人挖機租賃合同變更通知合同4篇
- 二零二五年度車輛收費員薪資待遇及福利協(xié)議材料詳盡條款4篇
- 第1課 隋朝統(tǒng)一與滅亡 課件(26張)2024-2025學年部編版七年級歷史下冊
- 2025-2030年中國糖醇市場運行狀況及投資前景趨勢分析報告
- 【歷史】唐朝建立與“貞觀之治”課件-2024-2025學年統(tǒng)編版七年級歷史下冊
- 冬日暖陽健康守護
- 水處理藥劑采購項目技術方案(技術方案)
- 2024級高一上期期中測試數(shù)學試題含答案
- 盾構標準化施工手冊
- 天然氣脫硫完整版本
- 山東省2024-2025學年高三上學期新高考聯(lián)合質量測評10月聯(lián)考英語試題
- 不間斷電源UPS知識培訓
- 三年級除法豎式300道題及答案
評論
0/150
提交評論