




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第二课 bmp图片格式解析<一>.BMP格式定义BMP文件格式是Windows操作系统推荐和支持的图像文件格式,是一种将内存或显示器的图像数据不经过压缩而直接按位存盘的文件格式,故称位图(bitmap),其扩展名为BMP。BMP图像文件被分为4个部分:a.位图文件头 b.位图信息头 c.颜色表 d.位图数据a.颜色表中RGBQUAD结构数据的个数有biBitCount来确定:当biBitCount=1,4,8时,分别有2,16,256个表项;当biBitCount=24时,没有颜色表项。位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:typedef struct
2、tagBITMAPINFO BITMAPINFOHEADER bmiHeader; / 位图信息头RGBQUAD bmiColors1; / 颜色表 BITMAPINFO;b.位图数据位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数: 当biBitCount=1时,8个像素占1个字节;当biBitCount=4时,2个像素占1个字节;当biBitCount=8时,1个像素占1个字节;当biBitCount=24时,1个像素占3个字节;Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充,
3、biSizeImage = (bi.biWidth * bi.biBitCount) + 31) & 31) / 8) * bi.biHeight。<二>.BMP图片在MFC工程中的定义存在2个未解问题:a. bmp结构时我定义成系统自带的结构,否则会多2个字节在图片最后为CD;b. 在read中malloc只能申请4字节的空间,但fread(,m_nImage,)读入位图大小个。第一步:添加BMP信息文件头文件新建创建ImageStruct.h包含BMP格式的文件头部分的结构。打开ImageStruct.h并添加代码:重点注意:1.bmp结构头必须定义成BITMAPFIL
4、EHEADER_ 不能定义成BITMAPFILEHEADER;因为在MFC中已存在BITMAPFILEHEADER的定义,在定义成它会显示重复定义。同时自己定义的在View.h和View.cpp中注意引用#include “ImageStruct.h”。2.在后面的引用bmp结构时我定义成系统自带的结构:BITMAPFILEHEADER bfh;BITMAPINFOHEADER bih;而不是BITMAPFILEHEADER_ ,因为MFC中用自带的定义图片头文件信息是正确的,但在位图信息块总会在文件最后多出2字节并默认为CD(0x16进制)。原因可能是自定义的图片头文件少2字节,在后面补充了
5、2字节。(未知)/*/* BMP位图文件包括4部分: */* 位图文件头结构BITMAPFILEHEADER */* 位图信息头结构BITMAPINFOHEADER */* 位图颜色表RGBQUAD */* 位图像素数据 */*/#ifndef _IMAGESTRUCT_#define _IMAGESTRUCT_/*14byte BMP文件头含有BMP文件的类型、大小、位图文件的保留字、位图数据距文件头的偏移量*/typedef struct T_BITMAPFILEHEADER WORD bfType; /2byte 位图文件的类型,必须为BM 0x424d DWORD bfSize; /4
6、byte 位图文件的大小,以字节为单位 WORD bfReserved1; /2byte 位图文件保留字,必须为0 WORD bfReserved2; /2byte 位图文件保留字,必须为0 DWORD bfOffBits; /4byte 位图数据距文件头的偏移量(字节) BITMAPFILEHEADER_;/*40byte BMP位图信息头用于说明位图的尺寸等信息*/typedef struct T_BITMAPINFOHEADER DWORD biSize; /本结构所占用字节数LONG biWidth; /位图的宽度,以像素为单位LONG biHeight; /位图的高度,以像素为单位W
7、ORD biPlanes; /目标设备的级别,必须为1WORD biBitCount; /每个像素所需的位数,必须是1(双色)、4(16色)、8(256色)或24(真彩色)之一DWORD biCompression; /位图压缩类型,必须是 0(不压缩)1(BI_RLE8压缩类型)或2(BI_RLE压缩类型)之一DWORD biSizeImage; /位图的大小,以字节为单位LONG biXPelsPerMeter; /位图水平分辨率,每米像素数LONG biYPelsPerMeter; /位图垂直分辨率,每米像素数DWORD biClrUsed; /位图实际使用的颜色表中的颜色数DWORD
8、biClrImportant; /位图显示过程中重要的颜色数 BITMAPINFOHEADER_;/*BMP位图颜色表*/typedef struct T_RGBQUAD BYTE rgbBlue; /蓝色的亮度(值范围为0255) BYTE rgbGreen; /绿色的亮度(值范围为0255) BYTE rgbRed; /红色的亮度(值范围为0255) BYTE rgbReserved; /保留,必须为0 RGBQUAD_; #endif第二步:在.View.h中添加共有成员变量和成员函数1.找到.View.h头文件添加:#include "ImageStruct.h"2
9、.在Class CBmpDrawView : public Cview中的public中添加成员变量函数:public:/用来保存bmp格式图片bool SaveBmp(LPCSTR lpFileName); /用来读取bmp图片bool ReadBmp(); /用来显示指定位图jpg、gif的函数bool ShowJpgGif(CDC* pDC,CString strPath, int x, int y);/用来显示指定位图bmp的函数void ShowBitmap(CDC* pDC,CString BmpName);/*CBitmap m_bitmaplin; 创建临时位图对象进行处理*/
10、CBitmap m_bitmap; /创建位图对象CString EntName; /保存图像文件扩展名CString BmpName; /保存图像文件文件名intm_nWidth;/图像实际宽度intm_nHeight;/图像实际高度intm_nDrawWidth;/图像显示宽度intm_nDrawHeight;/图像显示高度DWORD m_nImage;/图像数据的字节数 只含位图 DWORD相当于long intDWORD m_nSize; /图像文件大小int m_nLineByte; /图像一行所占字节数intm_nBitCount; /图像每个像素所占位数intm_nPalette
11、; /位图实际使用的颜色表中的颜色数/*注意:信息头必须条用系统bmp的结构BITMAPFILEHEADER 否则会多2字节*/BITMAPFILEHEADER bfh; /全局变量文件头BITMAPINFOHEADER bih; /全局变量信息头RGBQUAD *m_pPal; /颜色表指针BYTE *m_pImage; /读入图片数据后的指针 BYTE相当于 unsigned charvirtual CBmpDrawView();第三步:添加readbmp函数添加函数的方法:a.在View.h的public中直接添加函数bool ReadBmp()像第二步中一样;然后在View.cpp中添
12、加函数:bool CBmpDrawView:ReadBmp()。b.选中ClassView区-选中View类右键-增加成员变量函数函数类型为bool函数名为ReadBmp()函数Access为public。程序会自动在View.cpp中添加函数:bool CBmpDrawView:ReadBmp()。c.添加代码:/*写入bmp格式图片过程*/bool CBmpDrawView:ReadBmp()FILE *fp = fopen(BmpName,"rb"); /读取bmp图片 BmpName为图片的绝对路径if(fp=0) AfxMessageBox("无法打开文
13、件!",MB_OK,0); return 0; /*读取文件头 全局变量bfh BITMAPFILEHEADER 定义在ImageStruct中*/*解决BMP格式倒置的方法 (CSDN) fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp);倒置*/fread(&bfh.bfType,sizeof(WORD),1,fp);fread(&bfh.bfSize,sizeof(DWORD),1,fp);fread(&bfh.bfReserved1,sizeof(WORD),1,fp);fread(&bfh.bfRese
14、rved2,sizeof(WORD),1,fp);fread(&bfh.bfOffBits,sizeof(DWORD),1,fp);m_nSize = bfh.bfSize; /图像文件的总字节数/*判断是否是bmp格式图片 'BM'*/if(bfh.bfType!=0x4d42) AfxMessageBox("不是BMP格式图片!",MB_OK,0); return 0; /*读取信息头*/*解决BMP格式倒置的方法fread(&bih,sizeof(BITMAPINFOHEADER),1,fp);倒置*/fread(&bih.bi
15、Size,sizeof(DWORD),1,fp);fread(&bih.biWidth,sizeof(LONG),1,fp);fread(&bih.biHeight,sizeof(LONG),1,fp);fread(&bih.biPlanes,sizeof(WORD),1,fp);fread(&bih.biBitCount,sizeof(WORD),1,fp);fread(&bih.biCompression,sizeof(DWORD),1,fp);fread(&bih.biSizeImage,sizeof(DWORD),1,fp);fread(
16、&bih.biXPelsPerMeter,sizeof(LONG),1,fp);fread(&bih.biYPelsPerMeter,sizeof(LONG),1,fp);fread(&bih.biClrUsed,sizeof(DWORD),1,fp);fread(&bih.biClrImportant,sizeof(DWORD),1,fp);if(bih.biSize!=sizeof(bih) AfxMessageBox("本结构所占用字节数出现错误"); return 0; /*位图压缩类型:必须是0(不压缩)、1(BI_RLE8压缩类型
17、)、2(BI_RLE压缩类型)之一*/if(bih.biCompression = BI_RLE8 | bih.biCompression = BI_RLE4) AfxMessageBox("位图被压缩!"); return 0; /*获取图像高宽和每个像素所占位数*/m_nHeight = bih.biHeight;m_nWidth = bih.biWidth;m_nDrawHeight = bih.biHeight;m_nDrawWidth = bih.biWidth;m_nBitCount = bih.biBitCount; /每个像素所占位数/*计算图像每行像素所占
18、的字节数(必须是4字节的倍数) 2种方法*/m_nLineByte = (m_nWidth*m_nBitCount/8+3)/4*4;m_nLineByte = (m_nWidth*m_nBitCount+31)/32*4;/*计算图片位图的大小 长*宽*3为24位bmp位图大小3表示rgb*/m_nImage = m_nLineByte * m_nHeight;/*位图实际使用的颜色表中的颜色数 biClrUsed 注:24位bmp不用改参数*/m_nPalette = 0; if(bih.biClrUsed) m_nPalette = bih.biClrUsed;/*申请位图空间 大小为位
19、图大小 m_nImage*/*注意:malloc只能申请4字节的空间(未知) 但fread(,m_nImage,)读入位图大小个*/m_pImage=(BYTE*)malloc(m_nImage);fread(m_pImage,m_nImage,1,fp);/*注意:要关闭fp*/fclose(fp);return true;第四步:添加保存menu控件和函数a.查看-建立类导向(Ctrl+W)-CpictureXSView(类名)-ID_FILE_SAVE(IDs列表)-COMMAND(Messages列表)-默认成员函数名为OnFileSave-Member Functions(成员函数)
20、中双击该函数进入函数编辑。b.注意:Ctrl+W把另存为也设置成与保存相同的函数。ID_FILE_SAVE_AS-COMMAN-函数OnFileSaveAs改名为OnFileSave。c.添加代码:/*文件保存*/void CBmpDrawView:OnFileSave() / TODO: Add your command handler code hereCString filter;filter="所有文件(*.*)|*.bmp;*.jpg;*.gif;*.tiff| BMP(*.bmp)|*.bmp| JPG(*.jpg)|*.jpg| GIF(*.gif)|*.gif| TI
21、FF(*.tiff)|*.tiff|"/*重点:1-文件打开 0-文件保存*/CFileDialog dlg(0,NULL,NULL,OFN_HIDEREADONLY,filter,NULL); /产生保存对话框/*按下确定按钮*/if( dlg.DoModal() = IDOK )CString str;CString strName;CString filename;str = dlg.GetPathName(); /获取文件的路径filename = dlg.GetFileTitle(); /获取文件名 int nFilterIndex=dlg.m_ofn.nFilterInd
22、ex;if( nFilterIndex = 2 ) /当用户选择文件过滤器为".BMP"时str = str + ".bmp" /自动加扩展名.bmpSaveBmp(str); /保存bmp图片 就是一个写出图片的过程 AfxMessageBox("图片保存成功",MB_OK,0);第五步:添加保存函数SaveBmp添加函数原理同第三步添加Readbmp函数,在添加下列代码:/*保存bmp格式图片 写出图片的过程 只处理24像素的图片 该图片无调色板*/bool CBmpDrawView:SaveBmp(LPCTSTR lpFileN
23、ame)/*lpFileName为位图文件路径名*/AfxMessageBox(lpFileName);FILE *fpo = fopen(BmpName,"rb");FILE *fpw = fopen(lpFileName,"wb");fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);/*malloc只能申请4字节的空间 (未知)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 宿舍合同协议书
- 沙发合同协议书
- 瓷砖产品买卖合同协议书
- 霍邱幼师考编试题及答案
- 服务合同协议书范本模板
- 纺织行业中可持续发展的重要性试题及答案
- 车间租赁合同协议书每章
- 阿里巴巴决赛试题及答案
- 工厂买卖合同协议书范本
- 二衬合同协议书
- 2025届贵州省遵义第四中学高考全国统考预测密卷英语试卷含解析
- 2025年北京市丰台区九年级初三一模物理试卷(含答案)
- 中医内科学胸痹课件
- 2025广西广投临港工业有限公司社会招聘45人笔试参考题库附带答案详解
- 铜川易源电力实业有限责任公司招聘笔试真题2024
- 厨房清洁劳动课件
- 2025-2030中国桥塞行业市场现状供需分析及投资评估规划分析研究报告
- 土地旋耕合同协议书范本
- 山西省太原市2025年高三年级模拟考试(二)历史试题及答案
- 4-08-10-02 国家职业标准化工生产现场技术员(试行) (2025年版)
- 2025年云南烟草专卖局招聘人员笔试备考试题
评论
0/150
提交评论