BMP文件的读取与写入
来源:互联网 发布:服装cad软件排名 编辑:程序博客网 时间:2024/04/28 13:04
注:BMP文件格式在这里只做简单介绍,详细介绍可以参看我整理的这个文档<a target=_blank href="http://download.csdn.net/detail/zhangyi19930704/9262043">点击打开链接</a>
1、BMP文件格式
BMP文件主要包含四个部分:位图文件头,位图信息头,位图调色板,位图数据。
用结构体表示就是:
<span style="background-color: rgb(255, 255, 255);"><span style="font-size:18px;"></span></span><pre name="code" class="cpp"><pre name="code" class="cpp"><span style="color:#3366ff;"><span style="white-space:pre"></span>typedef struct tagBITMAP_FILE{ <span style="white-space:pre"></span>BMPHeader bitmapheader; <span style="white-space:pre"></span>BMPInfoHeader bitmapinfoheader; <span style="white-space:pre"></span>PALETTEENTRY palette[256]; <span style="white-space:pre"></span>UCHAR *buffer; <span style="white-space:pre"></span>} BITMAP_FILE;</span>
其中位图文件头结构体为:
<span style="font-size:18px;color:#3366ff;"><span style="white-space:pre"></span>typedef struct{<span style="white-space:pre"></span>short type;<span style="white-space:pre"></span>int size;<span style="white-space:pre"></span>short reserved1;<span style="white-space:pre"></span>short reserved2;<span style="white-space:pre"></span>int offset;<span style="white-space:pre"></span>} BMPHeader;//该结构体总共2+4+2+2+4=14字节</span>位图信息头结构体为:
<span style="font-size:18px;color:#3366ff;"><span style="white-space:pre"></span>typedef struct<span style="white-space:pre"></span>{<span style="white-space:pre"></span>int size;<span style="white-space:pre"></span>int width;<span style="white-space:pre"></span>int height;<span style="white-space:pre"></span>short planes;<span style="white-space:pre"></span>short bitsPerPixel;<span style="white-space:pre"></span>unsigned compression;<span style="white-space:pre"></span>unsigned imageSize;<span style="white-space:pre"></span>int xPelsPerMeter;<span style="white-space:pre"></span>int yPelsPerMeter;<span style="white-space:pre"></span>int clrUsed;<span style="white-space:pre"></span>int clrImportant;<span style="white-space:pre"></span>} BMPInfoHeader;</span>位图调色板结构体为(24位、32为真彩色图像没有调色板,详细介绍可以查看本文开始时的链接文档,内有测试):
<span style="font-size:18px;color:#3366ff;"><span style="white-space:pre"></span>typedef struct tagPALETTEENTRY { <span style="white-space:pre"></span>BYTE peBlue; <span style="white-space:pre"></span>BYTE peGreen; <span style="white-space:pre"></span>BYTE peRed; <span style="white-space:pre"></span>BYTE peFlags; <span style="white-space:pre"></span>} PALETTEENTRY; </span>位图数据自己定义为char类型字符数组即可。
<span style="font-size:18px;color:#3366ff;"><span style="white-space:pre"></span>char* imagedata = (char* ) malloc (sizeof(char) * width * height)</span>
注:由于结构体内部存在字节对其原则,在代码实现阶段,声明结构体时前面加上#pragma pack(1),表示该申明之后的结构体以1字节对齐
2、读入图像文件
<img src="http://img.blog.csdn.net/20151112134014958" alt="" />
初始定义变量:(此处以8位灰度BMP图像为例,包含调色板信息,24为真彩色图像没有调色板信息)
<span style="white-space:pre"></span><span style="color:#3366ff;">int width;int height;int size;int offset;int paletsize;BMPHeader hdr;BMPInfoHeader infoHdr;PALETTEENTRY * Palet = NULL;unsigned char * imagedata = NULL;</span>
首先使用fopen以可读二进制方式打开该BMP图像文件(打开成功与否,读取成功与否等异常情况在这里不做赘述):
<span style="white-space:pre"></span><span style="color:#3366ff;">FILE *fp = fopen("test.bmp", "rb");</span>读取文件头信息:
<span style="font-size:18px;"><span style="white-space:pre"></span><span style="color:#3366ff;">fread(&hdr, sizeof(hdr), 1, fp);</span></span>读取信息头信息:
<span style="white-space:pre"></span><span style="color:#3366ff;">fread(&infoHdr, sizeof(infoHdr), 1, fp);</span>接下来可以获取文件头和信息头内部信息
<span style="white-space:pre"></span><pre name="code" class="html"><span style="white-space:pre"></span><span style="color:#3366ff;">paletsize = infoHdr.clrUsed;width = infoHdr.width;height = infoHdr.height;<span style="white-space:pre"></span>offset = hdr.offset;</span>为调色板申请空间,并读入该图像的调色板信息到申请的空间中
<span style="white-space:pre"></span><span style="color:#3366ff;">Palet = (PALETTEENTRY *)malloc(sizeof(PALETTEENTRY) * paletsize);fread(Palet, sizeof(PALETTEENTRY), paletsize, fp);</span>申请图像数据空间,并将图像数据读入申请的字符数组中,注意对齐操作,由于Windows在进行行扫描的时候最小的单位为4个字节,所以当图片宽 X 每个像素的字节数 != 4的整数倍时要在每行的后面补上缺少的字节,以0填充,当做补充字节。详细内容可以查看之前文档
<span style="color:#3366ff;">imagedata = (unsigned char *)malloc(sizeof(char) * width*height);int skip = 4-(width%4)%4;if (4 == skip)skip = 0;for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){imagedata[i*width + j] = fgetc(fp);}for (int j = 0; j < skip; j++)fgetc(fp);}</span>至此,test.bmp的图像就读入到imagedata数组中了。至于文件头、信息头和调色板信息就读入到hdr,infoHdr,Palet中了。
3、图像数据处理
如果要用GPU做图像处理,最好将imagedata数据变换为浮点类型数据,因为GPU非常适合处理浮点运算。
直接对imagedata数据进行操作,加减乘除等等,可以用于做图像去噪、增强、去雾等。
4、写入图像数据
与读入图像数据类似,写图像的顺序和读图像相同。
打开要写入的图像:
<span style="white-space:pre"></span><span style="color:#3366ff;">FILE* fpOut = fopen("out.bmp", "wb");</span>
首先定位到文件开头:
<span style="white-space:pre"></span><span style="color:#3366ff;">fseek(fpOut, 0, SEEK_SET);</span>读入文件头:
<span style="color:#3366ff;">fwrite(&hdr, sizeof(hdr), 1, fpOut)</span>;读入信息头:
<span style="color:#3366ff;">fwrite(&infoHdr, sizeof(infoHdr), 1, fpOut);</span>读入调色板信息:
<span style="white-space:pre"></span><span style="color:#3366ff;">fwrite(Palet, sizeof(PALETTEENTRY), paletsize, fpOut);</span>读入实际数据:
<span style="white-space:pre"></span><span style="color:#3366ff;">for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){fputc(imagedata[i*width + j], fpOut);}for (int j = 0; j < skip; j++)fputc(0, fpOut);}</span>注意关闭文件指针!
至此,BMP文件的读取和写入完成了。
0 0
- BMP文件的读取与写入
- BMP 的读取与写入
- 文件的读取与写入
- BMP文件的读取与显示
- BMP文件的读取
- 读取与写入文件
- c#excel文件的读取与写入
- asp.net文件的读取与写入
- IOS XML文件的读取与写入
- IOS XML文件的读取与写入
- IO流的文件写入与读取
- IO流的文件写入与读取
- 关于文件的写入与读取
- Android 文件的读取与写入
- C++ ini文件的读取与写入
- 文件的顺序写入与读取
- 文件的随机写入与读取
- MFC .ini文件的读取与写入
- 培养思考的意识
- Event事件
- 关于样式的覆盖
- [转]C#:用SqlBulkCopy来实现批量插入数据
- Range Sum Query - Immutable
- BMP文件的读取与写入
- 3D开发基础之投影,变换,光照,纹理
- mvc 执行说明 再次写
- 孩子指针表示法关于前序遍历的括号表示和凹入表示
- 实验周作业~~QQ聊天记录的处理
- java访问权限控制表
- 多线程知识总结
- 黑马程序员——OC基础01—类和对象
- Java类笔试简答