版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 石河子大學(xué)《食品工程原理二》2021-2022學(xué)年第一學(xué)期期末試卷
- 石河子大學(xué)《現(xiàn)代人工智能技術(shù)》2023-2024學(xué)年期末試卷
- 石河子大學(xué)《家畜繁殖學(xué)》2022-2023學(xué)年第一學(xué)期期末試卷
- 沈陽理工大學(xué)《自動(dòng)控制理論》2021-2022學(xué)年期末試卷
- 沈陽理工大學(xué)《建筑模型制作與工藝》2021-2022學(xué)年第一學(xué)期期末試卷
- 沈陽理工大學(xué)《電工與電子技術(shù)實(shí)驗(yàn)》2023-2024學(xué)年期末試卷
- 光伏代理商合同范本
- 沈陽理工大學(xué)《環(huán)境設(shè)計(jì)》2021-2022學(xué)年第一學(xué)期期末試卷
- 海事法院 合同解除 典型案例
- 合同到期的續(xù)簽申請(qǐng)書
- 古詩三首《江南春》+公開課一等獎(jiǎng)創(chuàng)新教案+教學(xué)闡釋+素材
- 2024時(shí)事政治考試題庫(基礎(chǔ)題)
- 《學(xué)會(huì)專注高效學(xué)習(xí)》初中主題班會(huì)課件
- TSDPIA 05-2022 寵物貓砂通用技術(shù)規(guī)范
- 空調(diào)工程評(píng)標(biāo)辦法
- 血液透析血標(biāo)本采集
- 孫子兵法與兵家智慧
- 果樹病蟲害防治管理論文
- 采動(dòng)影響的基本規(guī)律及其應(yīng)用
- 油井動(dòng)液面檢測(cè)新技術(shù)
- 糕點(diǎn)類產(chǎn)品出廠檢驗(yàn)報(bào)告
評(píng)論
0/150
提交評(píng)論