实验一bmp位图的读取显示放大缩小二值化和反色.docx
- 文档编号:11113388
- 上传时间:2023-02-25
- 格式:DOCX
- 页数:19
- 大小:638.36KB
实验一bmp位图的读取显示放大缩小二值化和反色.docx
《实验一bmp位图的读取显示放大缩小二值化和反色.docx》由会员分享,可在线阅读,更多相关《实验一bmp位图的读取显示放大缩小二值化和反色.docx(19页珍藏版)》请在冰豆网上搜索。
实验一bmp位图的读取显示放大缩小二值化和反色
(数字图像处理)实验报告
实验名称实验一bmp位图的读取、显示、放大缩小、二值化和反色
实验时间
专业班级学号姓名
成绩教师评语:
一、
实验目的
1、掌握windowsBMP格式位图文件的基本格式。
会使用VC++读取图像数据并显示。
2、在读取BMP格式位图的的基础上增加对图像的放大、缩小、二值化和反色的功能。
二、实验内容
1、在VC6.0环境下,生成MFC应用程序框架。
2、在已生成的应用程序中,加BMP位图读取与显示的代码,从已有文件中读取bmp格式文件并在视图中显示。
3、在生成的MFC应用程序框架下建立对应的消息响应函数,实现对已在视图中显示的图像的放大、缩小、二值化和反色的具体操作。
三、实验原理具体操作步骤及结果截图
基本原理:
BMP位图文件格式
BMP位图文件中主要由4部分内容组成:
1、文件头BITMAPFILEHEADER为一STRUCTURE:
typedefstructtagBITMAPFILEHEADER{
WORDbfType;//文件类型,必须为“BM”或0x424d
DWORDbfSize;//文件大小
WORDbfReserved1;//保留
WORDbfReserved2;//保留
DWORDbfOffBits;//从文件头到实际位图数据的偏移字节数
}BITMAPFILEHEADER,FAR*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
2、位图信息头BITMAPINFOHEADER,定义如下:
typedefstructtagBITMAPINFOHEADER{
DWORDbiSize;//structuresize
LONGbiWidth;//imagewidth
LONGbiHeight;//imageheight
WORDbiPlanes;//valueis1
WORDbiBitCount;//colorbits
DWORDbiCompression;//compressionornot
DWORDbiSizeImage;//Imagesize=width*height(其中width必须为4的倍数。
LONGbiXPelsPerMeter;//
LONGbiYPelsPerMeter;
DWORDbiClrUsed;//
DWORDbiClrImportant;
}BITMAPINFOHEADER,FAR*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;
3、调色板
typedefstructtagRGBQUAD{
BYTErgbBlue;
BYTErgbGreen;
BYTErgbRed;
BYTErgbReserved;
}RGBQUAD;用于存放图像的颜色。
4、图像的实际数据。
对于2色图,用1位表示像素的值。
对于16色图,用4位表示像素的值。
对于256色图,一个字节刚好表示1个像素。
对于用到调色板的位图,图像数据就是该像素颜色在调色板中索引值,对于真彩色,不用调色板,三个字节的数据分别代表图像的B、G、R。
实验详细步骤
1、生成一名为zhengquan的基于MFC的应用程序框架:
选择file菜单new选项,在打开的窗口中选择project选项,选中MFCAppWizard(exe)。
并在projectname输入zhengquan,选择存放project的位置。
如下图所示。
选择ok,进入下一步。
选择singledocument,并在最后CdipView类的基类中选择CscrollView,使应用程序视图具有滚动条。
2、在应用程序中加入具体的函数和变量。
(1)在CzhengquanView中加入如入变量:
public:
intm_x;
HBITMAPm_Bmp;
LPVOIDm_ColorList;
LPBYTEm_Image;
LPBITMAPINFOHEADERm_DibHead;
enumallocate{None,crtallocate,heapallocate};
allocatem_nBmpallocate;
allocatem_nImageallocate;
DWORDm_ImageSize;
intm_nPalette;
HANDLEm_hFile;
HANDLEm_hMap;
LPVOIDm_lpvFile;
HPALETTEm_hPalette;
HGLOBALm_hGlob;
并利用ClassWizard向CzhengquanView类中加入如下成员函数。
voidzftjh(unsignedchar*lpDib,longlWidth,longlHeight);
voidSetPaletteSize(intnBitCount);
voidClear();
BOOLReadFile(CFile*pFile);
BOOLSetPalette();
BOOLGetPalette();
BOOLDibToDC(CDC*pDC,CSizesize);
BOOLMemToDib(LPVOIDlmem);
CSizeGetDibSize();
然后将对应的代码进行复制让其实现功能,代码如下:
voidCZhengquanView:
:
SetPaletteSize(intnBitCount)
{
if(m_DibHead->biSize!
=sizeof(BITMAPINFOHEADER)){
thrownewCException;
}
m_ImageSize=m_DibHead->biSizeImage;
if(m_ImageSize==0){
DWORDdwBytes=((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==0)){
switch(nBitCount){
case1:
m_nPalette=2;
break;
case4:
m_nPalette=16;
break;
case8:
m_nPalette=256;
break;
case16:
case24:
case32:
m_nPalette=0;
break;
default:
ASSERT(FALSE);
}
}
else{
m_nPalette=m_DibHead->biClrUsed;
}
ASSERT((m_nPalette>=0)&&(m_nPalette<=256));
}
voidCZhengquanView:
:
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;
}
elseif(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;
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;
}
BOOLCZhengquanView:
:
ReadFile(CFile*pFile)
{
intnCount,nSize;
BITMAPFILEHEADERbmfh;
Clear();
try{
nCount=pFile->Read((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER));
if(nCount!
=sizeof(BITMAPFILEHEADER)){
thrownewCException;
}
if(bmfh.bfType!
=0x4d42){
thrownewCException;
}
nSize=bmfh.bfOffBits-sizeof(BITMAPFILEHEADER);
m_DibHead=(LPBITMAPINFOHEADER)newchar[nSize];
m_nBmpallocate=m_nImageallocate=crtallocate;
nCount=pFile->Read(m_DibHead,nSize);
SetPaletteSize(m_DibHead->biBitCount);
GetPalette();
m_Image=(LPBYTE)newchar[m_ImageSize];
nCount=pFile->Read(m_Image,m_ImageSize);
}
catch(CException*tmpc){
AfxMessageBox("文件读取错误");
tmpc->Delete();
returnFALSE;
}
returnTRUE;
}
BOOLCZhengquanView:
:
SetPalette()
{
if(m_nPalette!
=0)
returnFALSE;
CClientDCdc(this);
CDC*pDC=&dc;
m_hPalette=:
:
CreateHalftonePalette(pDC->GetSafeHdc());
returnTRUE;
}
BOOLCZhengquanView:
:
GetPalette()
{
if(m_nPalette==0)
returnFALSE;
if(m_hPalette!
=NULL)
:
:
DeleteObject(m_hPalette);
LPLOGPALETTEpTempPalette=(LPLOGPALETTE)newchar[2*sizeof(WORD)+
m_nPalette*sizeof(PALETTEENTRY)];
pTempPalette->palVersion=0x30;
pTempPalette->palNumEntries=m_nPalette;
LPRGBQUADpRGBQuad=(LPRGBQUAD)m_ColorList;
for(inti=0;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); deletepTempPalette; returnTRUE; } BOOLCZhengquanView: : DibToDC(CDC*pDC,CSizesize) { if(m_DibHead==NULL) returnFALSE; if(m_hPalette! =NULL) { HDChdc=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); returnTRUE; } BOOLCZhengquanView: : MemToDib(LPVOIDlmem) { Clear(); m_DibHead=(LPBITMAPINFOHEADER)lmem; SetPaletteSize(m_DibHead->biBitCount); m_Image=(LPBYTE)m_ColorList+sizeof(RGBQUAD)*m_nPalette; GetPalette(); returnTRUE; } CSizeCZhengquanView: : GetDibSize() { if(m_DibHead==NULL) returnCSize(0,0); returnCSize((int)m_DibHead->biWidth,(int)m_DibHead->biHeight); } 之后利用资源编辑器,在主菜单中添加消息响应函数OnFileOpen(),并加入入下代码: CFileDialogfiledlg(TRUE,"bmp","*.bmp"); if(filedlg.DoModal()! =IDOK) return; CFilemyfile; myfile.Open(filedlg.GetPathName(),CFile: : modeRead); if(ReadFile(&myfile)==TRUE) Invalidate(); SetPalette(); 新建位图资源 •然后修改初始化函数和Ondraw函数,至此,上述代码已经完成读取并显示位图的功能。 数据存放在视图类中m_Image指向的内存区域。 显示的结果如下: 关于放大和缩小,首先新建按钮如下图: 然后按Ctrl+W导出消息函数添加窗口: 并添加消息响应函数实现功能。 其代码如下: 放大: CSizeDibsize=GetDibSize(); if((Dibsize.cx*m_x*1.2)<80000)\\\设置图像尺寸坐标 { if((Dibsize.cy*m_x*1.2)<100000) { m_x=(int)(m_x*1.2); Invalidate(); } } 缩小if(m_x>0.2) { m_x=(int)(m_x/1.2); Invalidate(); } 二值化和反色: 1、在主菜单下添加一名为“点运算”的菜单。 并添加两个分别名为“二值化”与“反色”的子菜单项。 分别给它们名为“IDM_ERZH”、“IDM_FANCE”的ID。 2、打开classwizard,分别为下述两菜单项加入相应的消息映射函数。 3、在函数体中加入二值化和反色的实现代码。 4、在两函数体最后加入更新视图的函数: Invalidate。 二值化代码: longw,h; longi,j; w=m_DibHead->biWidth; h=m_DibHead->biHeight; for(i=0;i for(j=0;j { if(*(m_Image+i*w+j)>50) *(m_Image+i*w+j)=255; else *(m_Image+i*w+j)=0; } Invalidate(); 反色代码: longw,h; w=m_DibHead->biWidth; h=m_DibHead->biHeight; longx,y; intf; for(y=0;y for(x=0;x { f=*(m_Image+y*w+x); *(m_Image+y*w+x)=255-f; } Invalidate(); 二值化和反色的结果如下: 原图 二值化后 反色后 思考与练习 1.我认为影响二值化的参数就是自己所设定的像素中间值,当大于这个值的时候像素点的值赋255,否则为0。 也就是下面程序代码中的50。 if(*(m_Image+i*w+j)>50) *(m_Image+i*w+j)=255; else *(m_Image+i*w+j)=0; 2.反色的原理就是把像素点的值换算成(现在显示的值=255-原来的值)。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 bmp 位图 读取 显示 放大 缩小 二值化