1、实验一bmp位图的读取显示放大缩小二值化和反色(数字图像处理)实验报告实验名称 实验一bmp位图的读取、显示、放大缩小、二值化和反色 实验时间 专业班级 学 号 姓 名 成 绩 教师评语: 一、实验目的1、掌握windows BMP格式位图文件的基本格式。会使用VC+读取图像数据并显示。2、在读取BMP格式位图的的基础上增加对图像的放大、缩小、二值化和反色的功能。二、实验内容1、在VC6.0环境下,生成MFC应用程序框架。2、在已生成的应用程序中,加BMP位图读取与显示的代码,从已有文件中读取bmp格式文件并在视图中显示。3、在生成的MFC应用程序框架下建立对应的消息响应函数,实现对已在视图中
2、显示的图像的放大 、缩小、二值化和反色的具体操作。三、实验原理具体操作步骤及结果截图基本原理:BMP位图文件格式BMP位图文件中主要由4部分内容组成:1、 文件头BITMAPFILEHEADER为一STRUCTURE:typedef struct tagBITMAPFILEHEADER WORD bfType;/文件类型,必须为“BM”或0x424d DWORD bfSize;/文件大小 WORD bfReserved1;/保留 WORD bfReserved2;/保留 DWORD bfOffBits;/从文件头到实际位图数据的偏移字节数 BITMAPFILEHEADER, FAR *LPBI
3、TMAPFILEHEADER, *PBITMAPFILEHEADER;2、 位图信息头BITMAPINFOHEADER,定义如下:typedef struct tagBITMAPINFOHEADER DWORD biSize;/structure size LONG biWidth;/image width LONG biHeight;/image height WORD biPlanes;/value is 1 WORD biBitCount;/color bits DWORD biCompression;/compression or not DWORD biSizeImage;/Imag
4、e size=width*height( 其中width必须为4的倍数。 LONG biXPelsPerMeter;/ LONG biYPelsPerMeter; DWORD biClrUsed;/ DWORD biClrImportant; BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;3、 调色板typedef struct tagRGBQUAD BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed;BYTE rgbReserved; RGBQUAD;用于存放图像的颜色。4、 图像的实
5、际数据。对于2色图,用1位表示像素的值。对于16色图,用4位表示像素的值。对于256色图,一个字节刚好表示1个像素。对于用到调色板的位图,图像数据就是该像素颜色在调色板中索引值,对于真彩色,不用调色板,三个字节的数据分别代表图像的B、G、R。实验详细步骤1、 生成一名为zhengquan的基于MFC的应用程序框架:选择file菜单new选项,在打开的窗口中选择project选项,选中MFC AppWizard(exe)。并在project name输入zhengquan ,选择存放project的位置。如下图所示。选择ok,进入下一步。选择single document,并在最后CdipVie
6、w类的基类中选择CscrollView,使应用程序视图具有滚动条。2、 在应用程序中加入具体的函数和变量。(1) 在CzhengquanView中加入如入变量: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
7、m_nPalette; HANDLE m_hFile; HANDLE m_hMap; LPVOID m_lpvFile; HPALETTE m_hPalette; HGLOBAL m_hGlob; 并利用ClassWizard向CzhengquanView类中加入如下成员函数。 void zftjh(unsigned char *lpDib,long lWidth,long lHeight); void SetPaletteSize(int nBitCount); void Clear(); BOOL ReadFile(CFile *pFile); BOOL SetPalette(); BOO
8、L GetPalette(); BOOL DibToDC(CDC* pDC,CSize size); BOOL MemToDib(LPVOID lmem); CSize GetDibSize();然后将对应的代码进行复制让其实现功能,代码如下:void CZhengquanView:SetPaletteSize(int nBitCount)if(m_DibHead-biSize != sizeof(BITMAPINFOHEADER) throw new CException; m_ImageSize = m_DibHead-biSizeImage; if(m_ImageSize = 0) DW
9、ORD dwBytes = (DWORD) m_DibHead-biWidth * m_DibHead-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
10、 = 0) switch(nBitCount) case 1: m_nPalette = 2; break; case 4: m_nPalette = 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 Read(LPVOID) &bmfh, sizeof(BIT
11、MAPFILEHEADER); 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; nCount = pFile-Read(m_DibHea
12、d, 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 CZhengquanView:SetPalette()if(m_nPalette!=0) return FALSE; CC
13、lientDC dc(this); CDC *pDC=&dc; m_hPalette=:CreateHalftonePalette(pDC-GetSafeHdc(); return TRUE;BOOL CZhengquanView:GetPalette()if(m_nPalette=0) return FALSE; if(m_hPalette!=NULL) :DeleteObject(m_hPalette); LPLOGPALETTE pTempPalette=(LPLOGPALETTE) new char2*sizeof(WORD)+ m_nPalette*sizeof(PALETTEENT
14、RY); pTempPalette-palVersion=0x30; pTempPalette-palNumEntries=m_nPalette; LPRGBQUAD pRGBQuad=(LPRGBQUAD)m_ColorList; for(int i=0;ipalPalEntryi.peRed=pRGBQuad-rgbRed; pTempPalette-palPalEntryi.peGreen=pRGBQuad-rgbGreen; pTempPalette-palPalEntryi.peBlue=pRGBQuad-rgbBlue; pTempPalette-palPalEntryi.peFl
15、ags=0; pRGBQuad+; m_hPalette=:CreatePalette(pTempPalette); delete pTempPalette; return TRUE;BOOL CZhengquanView: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); :Stre
16、tchDIBits(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 CZhengquanView:MemToDib(LPVOID lmem)Clear(); m_DibHead=(LPBITMAPINFOHEADER)lmem; SetPaletteSize(m_DibHead-biBitCount); m_Image=(LPBYTE)
17、m_ColorList+sizeof(RGBQUAD)*m_nPalette; GetPalette(); return TRUE;CSize CZhengquanView:GetDibSize()if(m_DibHead=NULL) return CSize(0,0); return CSize(int)m_DibHead-biWidth,(int)m_DibHead-biHeight);之后利用资源编辑器,在主菜单中添加消息响应函数OnFileOpen(),并加入入下代码:CFileDialog filedlg(TRUE,bmp,*.bmp); if(filedlg.DoModal()!=
18、IDOK) return; CFile myfile; myfile.Open(filedlg.GetPathName(),CFile:modeRead); if(ReadFile(&myfile)=TRUE) Invalidate(); SetPalette();新建位图资源 然后修改初始化函数和Ondraw函数,至此,上述代码已经完成读取并显示位图的功能。数据存放在视图类中m_Image指向的内存区域。显示的结果如下:关于放大和缩小,首先新建按钮如下图:然后按Ctrl+W导出消息函数添加窗口:并添加消息响应函数实现功能。其代码如下:放大:CSize Dibsize = GetDibSize
19、(); if (Dibsize.cx * m_x * 1.2) 80000) 设置图像尺寸坐标 if (Dibsize.cy * m_x * 1.2) 0.2) m_x = (int)(m_x / 1.2); Invalidate(); 二值化和反色:1、 在主菜单下添加一名为“点运算”的菜单。并添加两个分别名为“二值化”与“反色”的子菜单项。分别给它们名为“IDM_ERZH”、“IDM_FANCE”的ID。2、 打开classwizard,分别为下述两菜单项加入相应的消息映射函数。3、 在函数体中加入二值化和反色的实现代码。4、 在两函数体最后加入更新视图的函数:Invalidate。二值化
20、代码:long w,h; long i,j; w=m_DibHead-biWidth; h=m_DibHead-biHeight; for (i=0;ih;i+) for (j=0;j50) *(m_Image+i*w+j)=255; else *(m_Image+i*w+j)=0; Invalidate();反色代码:long w,h; w=m_DibHead-biWidth; h=m_DibHead-biHeight; long x,y; int f; for(y=0;yh;y+) for(x=0;x50) *(m_Image+i*w+j)=255; else *(m_Image+i*w+j)=0;2.反色的原理就是把像素点的值换算成(现在显示的值=255-原来的值)。