已阅读5页,还剩11页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验一 位图文件的读取与显示一、实验背景1 位图文件格式说明位图文件格式由四部分组成,如图 1所示,分别是位图文件头、位图信息头、调色板以及位图像素数据,其中调色板信息为可选信息,只有当每个像素的比特数小于或等于8(BITMAPINFOHEADER.biBitCount=8)时才存在,即为一个颜色查找表。需要注意的是,位图文件存储时为了提高内存访问的速度,每一行的字节数必须是4的倍数,即:如果一幅图像的宽度为253,每个像素用8bit表示,因此,该图像实际每行所占的存储空间数为253Byte,但为了与4对齐,存储时所用的存储空间为256Byte。具体而言,假设图像的宽度为w,每个像素用n比特表示,则图像每行像素所占的字节数为:(w * n + 31)/32 * 4图 1 位图文件格式说明2 位图文件读取位图文件的读取包括两步:(1)根据第1节中的位图文件格式说明,对位图文件进行解析;(2)根据读取的内容创建可供显示的位图句柄。 (1)位图文件解析 /open fileFILE *fp = NULL;fopen_s(&fp, strPath, _T(rb);if (fp = NULL)CString str = _T(File not exist: )+ strPath;AfxMessageBox(str);return 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.bmiHeader;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 compressed);return NULL;int nPalettes = bmInfoHeader.biClrUsed;if (nPalettes = 0 & bmInfoHeader.biBitCount = 8)nPalettes = 1 0)pBmInfo = new bytesizeof(BITMAPINFOHEADER) + nPalettes * sizeof(RGBQUAD);memcpy(pBmInfo, &bmInfoHeader, sizeof(BITMAPINFOHEADER);byte *pPalette = pBmInfo + sizeof(BITMAPINFOHEADER);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(pContents, nImageBytes, 1, fp);(2)将读取的内容转换为Bitmap句柄该步骤需使用系统函数CreateDIBitmap。CreateDIBitmap的函数说明如下:HBITMAP CreateDIBitmap(HDC hdc, CONST BITMAPINFOHEADER *lpbmih, DWORD fdwlnit, CONST VOID *lpblnit, CONST BITMAPINFO *lpbmi, UINT fuUsage);参数:hdc:设备环境句柄。lpbmih:指向位图信息头结构的指针,它可以是下列操作系统位图信息头之一:Fdwlnit:位标识集。它指定系统如何对位图的位进行初始化。CBM_INIT:如果设置了该标志,那么系统将使用lpblnit和lpbmi两个参数指向的数据 来对位图中的位进行初始化。如果没有该标志,那么表示上述两个参数指向的数据无效。如果fdwlnit为0,那么系统不会对位图的位进行初始化。lpblnit:该指针指向包含初始的位图数据的字节类型数组。数据格式与参数lpbmi指向的BITMAPINFO结构中的成员biBitCount有关。lpbmi:指向BITMAPINFO结构的旨针。该结构描述了参数lpbmi指向的数组的维数和颜色格式。fuUsage:表示BITMAPINFO结构的成员bmiColors是否初始化过,并且如果是,那么bmiColors是否包含明确的红、绿、蓝(RGB)值或调色板索引。参数fuUsage必须取下列值中的一个,这些值的含义为:DIB_PAL_COLORS:表示提供一个颜色表,并且该表由该位图要选入的设备环境的逻辑调色板的16位索引值数组组成。DIB_RGB_COLORS:表示提供一个颜色表,并且表中包含了原义的RGB值。 if (pBmInfo = NULL)/无调色板时,BITMAPINFO就等同于BITMAPINFOHEADERpBmInfo = (byte *)&bmInfo;/create DIB BitmapHDC hdc = GetDC(AfxGetMainWnd()-GetSafeHwnd();HBITMAP hBitmap = CreateDIBitmap(hdc, &bmInfoHeader, CBM_INIT, pContents, (BITMAPINFO *)pBmInfo, DIB_RGB_COLORS);delete pContents;if (nPalettes 0)delete pBmInfo;3 位图的显示位图的显示分为三步:(1)利用CreateCompatibleDC()函数创建兼容内存设备环境;(2)利用SelectObject()函数将位图对象放入兼容内存设备环境;(3)使用BitBlt()函数或者StrechBlt()函数将位图显示在屏幕上。BitBlt()只能按照位图原来的大小进行显示,而StrechBlt()可以对位图进行放大或缩小。CDC compDC;compDC.CreateCompatibleDC(pDC); /创建pDC兼容的设备环境compDC.SelectObject(pBitmap); /将位图对象放入兼容设备环境/显示位图BITMAP bitmap;pBitmap-GetBitmap(&bitmap); /获取位图信息pDC-BitBlt(0, 0, /位图显示位置bitmap.bmWidth, bitmap.bmHeight, /显示位图的宽度和高度&compDC, /位图所在兼容DC0, 0, /兼容DC中的位置SRCCOPY); /显示方式二、主要问题在Windows环境下,通过解析位图文件的格式,读入位图并进行显示,不能使用Windows中已有的API(如LoadImage函数)读取位图文件,即自己实现LoadImage函数的功能:LoadImage(NULL, “lenna.bmp”, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)3、 采取的解决方法1、 生成一名为Bitmap的基于MFC的应用程序框架: 选择“文件”菜单“新建”选项,在打开的窗口中选择“工程”选项,选中MFCAppWizard(exe)。并在“工程名称”中输入Bitmap,选择存放“工程”的位置。如下图所示: 选择确定,进入下一步。选择“单文档”,并在最后CdipView类的基类中选择CscrollView,使应用程序视图具有滚动条。2、在应用程序中加入具体的函数和变量。如上图所示,在FileView中,选择头文件中的BitmapView.h文件并打开,添加如下列的公共变量:public:intm_x;HBITMAPm_Bmp;LPVOIDm_ColorList;LPBYTEm_Image;LPBITMAPINFOHEADERm_DibHead;enumallocateNone,crtallocate,heapallocate;allocatem_nBmpallocate;allocatem_nImageallocate;DWORDm_ImageSize;intm_nPalette;HANDLEm_hFile;HANDLEm_hMap;LPVOIDm_lpvFile;HPALETTEm_hPalette;HGLOBALm_hGlob; 在ClassView中选择CGsmView单击右键选择添加成员函数,把下列函数加入到C+View类中voidSetPaletteSize(intnBitCount);voidClear();BOOLReadFile(CFile*pFile);BOOLSetPalette();BOOLGetPalette();BOOLDibToDC(CDC*pDC,CSizesize);BOOLMemToDib(LPVOIDlmem);CSizeGetDibSize();3、 把对应函数代码拷贝到新的函数中;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-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_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_nPaletteRead(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; 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:SetPalette()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*sizeof(WORD)+m_nPalette*sizeof(PALETTEENTRY);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.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-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 CBitmapView:MemToDib(LPVOID lmem)Clear();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、编译检验没有出现错误;出现显示位图的菜单框Bitmap,结果如下:5、 在程序资源中创建位图条为默认;经查资料,在这里简单介绍一下如何建立一个位图资源。新建一个VC+工程,取名为“Bitmap”,具体的步骤参考菜单实例中的工程创建,创建好后,单击主菜单中的“插入”“资源”,弹出“插入资源”对话框。或者单击项目工作区中的“Resource View”标签,激活资源视图选项卡,然后选中其中任一节点右键单击,在快捷菜单中选择“插入”命令,会弹出相同的资源对话框。在“插入资源”对话框中选择Bitmap,单击右边的“新建”按钮新建一个位图资源,其ID为IDB_BITMAP1(或者单击“引入”按钮,从文件中导入一个位图资源),如图下图所示:在项目工作区中的“Resource View”标签下,点鼠标右键选择Bitmap下的“IDB_BITMAP1”,选择“属性”命令,弹出属性对话框,如下图所示。在其中,对诸如ID、File name等属性取默认值。“位图属性”对话框在项目工作区中的“Resource View”标签下,双击Bitmap下的“IDB_BITMAP1”,在弹出的文件测览窗口中出现位图资源编辑器,如下图所示。在该编辑区里可以完成与画图程序同样的各种编辑功能,包括填充各种形状,擦去错误等,可在其中绘制期望的位图。位图资源编辑器绘制好位图后,单击“文件”“保存”命令保存资源文件。这样,一个位图资源就制作好了。在程序中,可利用CBitmap类的LoadBitmap函数来加载位图资源。6、修改OnInitialUpdate函数中的代码;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函数中的代码;void CBitmapView:OnDraw(CDC* pDC)CBitmapDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 山东省五莲县2027届物理高三第一学期期中达标检测试题含解析
- 2027届广东省肇庆联盟校物理高三第一学期期中教学质量检测试题含解析
- 2027届安徽省黄山市物理高二第一学期期中检测试题含解析
- 2026运动护具产品生命周期缩短背景下的研发加速机制研究
- 2026年CAAC无人机理论考试题库及参考答案详解
- 山西省晋中市祁县二中2027届高二上物理期末达标测试试题含解析
- 北京市北京第四中学2027届高二物理第一学期期末学业水平测试模拟试题含解析
- 2027届吉林省乾安县七中物理高二第一学期期末统考模拟试题含解析
- 2027届湖北省钢城第四中学物理高三上期中统考试题含解析
- 湖北省鄂州市华容高级中学2027届高三上物理期中学业水平测试模拟试题含解析
- 2026广东湛江市遂溪发展集团有限公司招聘15人(第二批)考试备考题库及答案详解
- 2026年重庆市部编版高一语文一轮复习第五单元文言文阅读测试题库试卷
- 2025秋新版道德与法治二年级上册教学工作计划及教学进度表
- 2026 年秋季开学:新时代教师师德师风建设专题培训
- 电梯困人应急演练总结报告
- 2026年幼儿园新生家长会后勤园长
- 2026高速铁路通讯行业市场供需分析及投资布局规划分析研究报告
- 工程伦理第2版
- (完整版)厂房翻新改造工程施工组织设计方案
- 社区胸痛健康教育
- 教育强国建设三年行动计划(2025-2027年)
评论
0/150
提交评论