首页 考试资料幻灯片工程技术公务员考试小学教学中学教学大学教学外语资料
00数 字 图 像 处 理 上 机 指 导


VC++数 字 图 像 处 理 上 机 指 导
(试用版)
桂进斌编著 适用专业:电子信息相关专业

昆明理工大学理学院

实验一、VC6.0 下 bmp 位图的读取与显示 实验目的:掌握 windows BMP 格式位图文件的基本格式。会使 用 VC++读取图像数据并显示。 实验内容: 1、 在 VC6.0 环境下,生成 MFC 应用程序框架。 2、 在已生成的应用程序中,加 BMP 位图读取与显示的代码, 从已有文件中读取 bmp 格式文件并在视图中显示。 实验原理及步骤: 基本知识:BMP 位图文件格式 BMP 位图文件中主要由 4 部分内容组成: 1、 文件头 BITMAPFILEHEADER 为一 STRUCTURE:

typedef struct tagBITMAPFILEHEADER { WORD bfType;//文件类型,必须为“BM”或 0x424d DWORD WORD WORD DWORD bfSize;//文件大小 bfReserved1;//保留 bfReserved2;//保留 bfOffBits;//从文件头到实际位图数据的 偏移字节数 } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; 2、 位图信息头 BITMAPINFOHEADER,定义如下:

typedef struct tagBITMAPINFOHEADER{ DWORD LONG LONG WORD WORD DWORD DWORD biSize;//structure size biWidth;//image width biHeight;//image height biPlanes;//value is 1 biBitCount;//color bits biCompression;//compression or not biSizeImage;//Image size=width*height( 其中 width必须为4的倍数。 LONG LONG DWORD DWORD biXPelsPerMeter;// biYPelsPerMeter; biClrUsed;// biClrImportant;

} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
3、 调色板

typedef struct tagRGBQUAD { BYTE BYTE BYTE BYTE rgbReserved; rgbBlue; rgbGreen; rgbRed;

} RGBQUAD;用于存放图像的颜色。 4、图像的实际数据。对于 2 色图,用 1 位表示像素的值。 对于 16 色图,用 4 位表示像素的值。对于 256 色图,一个 字节刚好表示 1 个像素。对于用到调色板的位图,图像数据 就是该像素颜色在调色板中索引值,对于真彩色,不用调色 板,三个字节的数据分别代表图像的 B、G、R。
1、 生成一名为 dip 的基于 MFC 的应用程序框架:选择 file 菜 单 new 选项, 在打开的窗口中选择 project 选项, 选中 MFC AppWizard(exe) 。并在 project name 输入 dip , 选择存放 project 的位置。如下图所示。

选择 ok, 进入下一步。 选择 single document, 并在最后 CdipView 类的基类中选择 CscrollView,使应用程序视图具有滚动条。具

体过程可参阅 VC++6.0 上机指导。 2、 在应用程序中加入具体的函数和变量。 (1) 在 CdipView.h 中加入如入变量:

public: int m_x; HBITMAP m_Bmp; LPVOID m_ColorList; LPBYTE m_Image; LPBITMAPINFOHEADER m_DibHead; enum allocate {None, crtallocate, heapallocate}; allocate m_nBmpallocate; allocate m_nImageallocate; DWORD m_ImageSize; int m_nPalette; HANDLE m_hFile; HANDLE m_hMap; LPVOID m_lpvFile; HPALETTE m_hPalette; HGLOBAL m_hGlob; 利用ClassWizard向CdipView类中加入如下成员函数。

void SetPaletteSize(int nBitCount);

void Clear(); BOOL ReadFile(CFile *pFile); BOOL SetPalette(); BOOL GetPalette(); BOOL DibToDC(CDC* pDC,CSize size); BOOL MemToDib(LPVOID lmem); CSize GetDibSize(); 并在具体的函数实现其功能,具体代码见附录 1。 (2) 利用资源编辑器,在主菜单中添加消息响应函数 OnFileOpen(),并加入下代码: CFileDialog filedlg(TRUE,"bmp","*.bmp"); if(filedlg.DoModal()!=IDOK) return;

CFile myfile; myfile.Open(filedlg.GetPathName(),CFile::modeRead); if(ReadFile(&myfile)==TRUE) Invalidate(); SetPalette(); (3)修改 OnDraw()函数,添加如下代码: BeginWaitCursor(); CSize DibSize = GetDibSize();

DibSize.cx *= m_x; DibSize.cy *= -m_x; DibToDC(pDC, DibSize); EndWaitCursor(); 附录 1:读取 bmp 位图的函数代码。
CSize CDipView::GetDibSize() { if(m_DibHead==NULL) return CSize(0,0); return CSize((int)m_DibHead->biWidth,(int)m_DibHead->biHeight); } BOOL CDipView::MemToDib(LPVOID lmem) { Clear(); m_DibHead=(LPBITMAPINFOHEADER)lmem; SetPaletteSize(m_DibHead->biBitCount); m_Image=(LPBYTE)m_ColorList+sizeof(RGBQUAD)*m_nPalette; GetPalette(); return TRUE; } BOOL CDipView::DibToDC(CDC *pDC, CSize size) { if(m_DibHead==NULL) return FALSE; if(m_hPalette!=NULL) { HDC hdc=pDC->GetSafeHdc(); ::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 CDipView::GetPalette() { if(m_nPalette==0) return FALSE; if(m_hPalette!=NULL) ::DeleteObject(m_hPalette); LPLOGPALETTE pTempPalette=(LPLOGPALETTE) new char[2*sizeof(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->palPalEntry[i].peRed=pRGBQuad->rgbRed; pTempPalette->palPalEntry[i].peGreen=pRGBQuad->rgbGreen; pTempPalette->palPalEntry[i].peBlue=pRGBQuad->rgbBlue; pTempPalette->palPalEntry[i].peFlags=0; pRGBQuad++; } m_hPalette=::CreatePalette(pTempPalette); delete pTempPalette; return TRUE; } BOOL CDipView::SetPalette() { if(m_nPalette!=0) return FALSE; CClientDC dc(this); CDC *pDC=&dc; m_hPalette=::CreateHalftonePalette(pDC->GetSafeHdc()); return TRUE; } BOOL CDipView::ReadFile(CFile *pFile) { int nCount, nSize; BITMAPFILEHEADER bmfh; Clear(); try {

nCount = 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 char[nSize]; m_nBmpallocate = m_nImageallocate = crtallocate; nCount = pFile->Read(m_DibHead, nSize); SetPaletteSize(m_DibHead->biBitCount); GetPalette(); m_Image = (LPBYTE) new char[m_ImageSize]; nCount = pFile->Read(m_Image, m_ImageSize); } catch(CException* tmpc) { AfxMessageBox("文件读取错误"); tmpc->Delete(); return FALSE; } return TRUE; } void CDipView::Clear() { if(m_hFile == NULL) return; ::UnmapViewOfFile(m_lpvFile); ::CloseHandle(m_hMap); ::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_Bmp); m_nBmpallocate = m_nImageallocate = None;

123

 


 

  【Top

最新搜索