BMP文件简介

BMP(全称Bitmap)是Windows操作系统中的标准图像文件格式,可以分成两类:设备有向量相关位图(DDB)和设备无向量相关位图(DIB),使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。

BMP文件格式

BMP文件主要有四部分组成,位图头、位图信息、调色板、位图数据。

位图头

保存文件的总体信息

  • 字节 #0-1 保存位图文件的标识符,用于标识BMP和DIB文件的魔数,一般为0x42 0x4D,即ASCII的BM。以下为可能的取值:

    BM – Windows 3.1x, 95, NT, … etc.

    BA – OS/2 struct Bitmap Array

    CI – OS/2 struct Color Icon

    CP – OS/2 const Color Pointer

    IC – OS/2 struct Icon

    PT – OS/2 Pointer
  • 字节 #2-5 使用一个dword保存位图文件大小。
  • 字节 #6-9 是保留部分,留做以后的扩展使用,对实际的解码格式没有影响。
  • 字节 #10-13 保存位图数据位置的地址偏移,也就是起始地址。

位图信息

这部分告诉应用程序图像的详细信息,在屏幕上显示图像将会使用这些信息

  • 字节 #14-17 定义以下用来描述影像的区块(BitmapInfoHeader)的大小。
  • 字节 #18-21 保存位图宽度(以像素个数表示)。
  • 字节 #22-25 保存位图高度(以像素个数表示)。
  • 字节 #26-27 保存所用彩色位面的个数。不经常使用。
  • 字节 #28-29 保存每个像素的位数,它是图像的颜色深度。常用值是1、4、8(灰阶)和24(彩色)。
  • 字节 #30-33 定义所用的压缩算法。允许的值是0、1、2、3、4、5。

    0 - 没有压缩(也用BI_RGB表示)

    1 - 行程长度编码 8位/像素(也用BI_RLE8表示)

    2 - 行程长度编码4位/像素(也用BI_RLE4表示)

    3 - Bit field(也用BI_BITFIELDS表示)

    4 - JPEG图像(也用BI_JPEG表示)

    5 - PNG图像(也用BI_PNG表示)

调色板

暂时不做介绍

位图数据

在典型的24位位图下,一个像素由24bit,即3个字节(R\G\B)组成。

C语言代码

获取文件大小

int getBmpFileSize(FILE * fpbmp)
{
int size = 0; fseek(fpbmp, 2, SEEK_SET);
fread(&size, sizeof(char), 4, fpbmp); return size;
}

获取文件尺寸

int getBmpWidth(FILE* fpbmp)
{
int width = 0; fseek(fpbmp, 18L, SEEK_SET);
fread(&width, sizeof(char), 4, fpbmp); return width;
} int getBmpHeight( FILE* fpbmp )
{
int height = 0; fseek(fpbmp, 22L, SEEK_SET);
fread(&height, sizeof(char), 4, fpbmp); return height;
}

获取文件偏移量

int getOffset(FILE * fpbmp)
{
int offset = 0; fseek(fpbmp, 10L, SEEK_SET);
fread(&offset, sizeof(char), 4, fpbmp); return offset;
}

读取文件数据示例

对于一个3*3的BMP文件,三行分别是纯色的RGB分量



int readBmpData( FILE* fpbmp )
{
int i = 0, j = 0; int offset = getOffset(fpbmp);
int width = getBmpWidth(fpbmp);
int height = getBmpHeight(fpbmp); unsigned char * pix = NULL; //one pix have 3 byte data( R G B )
pix = malloc( 4 * sizeof( unsigned char ) ); fseek(fpbmp, offset, SEEK_SET); // Jump to data part for( i = 0; i < height; i++ )
{
for( j = 0; j < width; j++ )
{
fread(pix, 3, 1, fpbmp);
printf("(%3d,%3d,%3d) ",pix[0],pix[1],pix[2]);
} /*printf(",");
for(;(j)%4!=0;j++)
{
fread(pix, 3, 1, fpbmp);
printf("(%3d,%3d,%3d) ",pix[0],pix[1],pix[2]);
}*/
printf("\n");
}
return 0;
}

一个问题

等等,头部54字节,图像9个像素=27字节,加起来一共81字节,可是文件有90字节啊!剩下的4个字节呢?

不妨把注释部分取消注释试一下!

原来,windows里每行不足4字节的整数倍,会自动补0!所以三行多出了3个像素=9字节

完整程序

#include <stdio.h>

int getBmpWidth(FILE* fpbmp);
int getBmpHeight( FILE* fpbmp );
int getBmpFileSize(FILE * fpbmp);
int getBmpPixBits(FILE * fpbmp);
int getOffset(FILE * fpbmp);
int readBmpData( FILE* fpbmp ); int main()
{
FILE * fp_read ; fp_read = fopen("test.bmp","rb"); if(fp_read == NULL)
{
printf("文件打开失败\r\n");
return 0;
} printf("图像宽度:%d\n",getBmpWidth(fp_read));
printf("图像高度:%d\n",getBmpHeight(fp_read));
printf("文件大小:%d字节\n",getBmpFileSize(fp_read));
printf("像素位数:%d\n",getBmpPixBits(fp_read));
printf("偏移:%d\n",getOffset(fp_read)); readBmpData(fp_read); return 0;
} int readBmpData( FILE* fpbmp )
{
int i = 0, j = 0; int offset = getOffset(fpbmp);
int width = getBmpWidth(fpbmp);
int height = getBmpHeight(fpbmp); unsigned char * pix = NULL; //one pix have 3 byte data( R G B )
pix = malloc( 4 * sizeof( unsigned char ) ); fseek(fpbmp, offset, SEEK_SET); // Jump to data part for( i = 0; i < height; i++ )
{
for( j = 0; j < width; j++ )
{
fread(pix, 3, 1, fpbmp);
printf("(%3d,%3d,%3d) ",pix[0],pix[1],pix[2]);
} printf(",");
for(;(j)%4!=0;j++)
{
fread(pix, 3, 1, fpbmp);
printf("(%3d,%3d,%3d) ",pix[0],pix[1],pix[2]);
}
printf("\n");
}
return 0;
} //获取像素位数
int getBmpPixBits(FILE * fpbmp)
{
int bits = 0; fseek(fpbmp, 28, SEEK_SET);
fread(&bits, sizeof(char), 2, fpbmp); return bits;
} int getBmpFileSize(FILE * fpbmp)
{
int size = 0; fseek(fpbmp, 2, SEEK_SET);
fread(&size, sizeof(char), 4, fpbmp); return size;
} int getBmpWidth(FILE* fpbmp)
{
int width = 0; fseek(fpbmp, 18L, SEEK_SET);
fread(&width, sizeof(char), 4, fpbmp); return width;
} int getBmpHeight( FILE* fpbmp )
{
int height = 0; fseek(fpbmp, 22L, SEEK_SET);
fread(&height, sizeof(char), 4, fpbmp); return height;
} int getOffset(FILE * fpbmp)
{
int offset = 0; fseek(fpbmp, 10L, SEEK_SET);
fread(&offset, sizeof(char), 4, fpbmp); return offset;
}

BMP文件解析的更多相关文章

  1. BMP文件解析【转】

    本文转载自:http://blog.csdn.net/Blues1021/article/details/44954817 BMP文件通常是不压缩的,所以它们通常比同一幅图像的压缩图像文件格式要大很多 ...

  2. 数据恢复培训资料:BMP文件详解

    BMP是一种与硬件设备无关的图像文件格式,使用非常广.它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BblP文件所占用的空间很大.BMP文件的图像深度可选lbit.4bit.8 ...

  3. Dicom格式文件解析器[转]

    Dicom格式文件解析器   Dicom全称是医学数字图像与通讯,这里讲的暂不涉及通讯那方面的问题 只讲*.dcm 也就是diocm格式文件的读取,读取本身是没啥难度的 无非就是字节码数据流处理.只不 ...

  4. AS3.0 位图(BMP)解析类

    /** * *-----------------------------* * | *** BMP格式解析类 *** | * *-----------------------------* * * 编 ...

  5. Matlab 读取文件夹中所有的bmp文件

    将srcimg文件下的bmp文件转为jpg图像,存放在dstimg文件夹下 str = 'srcimg'; dst = 'dstimg'; file=dir([str,'\*.bmp']); :len ...

  6. CocosStudio文件解析工具CsdAnalysis

    起因 因为工作需要,所以需要使用CocosStudio来制作界面动画什么的.做完了发现需要找里边对象的时候会有很长一串代码,感觉不是很爽.之前写OC代码的时候可以吧程序中的对象指针跟编辑器中的对象相对 ...

  7. 通过正则表达式实现简单xml文件解析

    这是我通过正则表达式实现的xml文件解析工具,有些XHTML文件中包含特殊符号,暂时还无法正常使用. 设计思路:常见的xml文件都是单根树结构,工具的目的是通过递归的方式将整个文档树装载进一个Node ...

  8. 图像预处理第9步:存为.bmp文件

    //图像预处理第9步:将最终标准化后的字符图像分为单个单个的HDIB保存,并存为.bmp文件 void CChildView::OnImgprcToDibAndSave() { unsigned ch ...

  9. Bitmap文件格式+生成一个BMP文件

    Bitmap的文件格式: #define UINT16 unsigned short #define DWORD unsigned int #define WORD short #define LON ...

随机推荐

  1. ORACLE跨数据库查询的方法

    原文地址:http://blog.csdn.net/huzhenwei/article/details/2533869 本文简述了通过创建database link实现Oracle跨数据库查询的方法 ...

  2. Kafka设计解析(六)- Kafka高性能架构之道

    本文从宏观架构层面和微观实现层面分析了Kafka如何实现高性能.包含Kafka如何利用Partition实现并行处理和提供水平扩展能力,如何通过ISR实现可用性和数据一致性的动态平衡,如何使用NIO和 ...

  3. Centos7 下Jenkins 安装

    前言:什么是Jenkins? Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. 一.下载 wg ...

  4. WPFの命中测试

    概述:  WPF中的Canvas是常用的一个绘图控件,可以方便地在Canvas中添加我们需要处理的各种元素如:图片.文字等.但Canvas中元素增加到一定数量,并且有重合的时候,我们如何通过在Canv ...

  5. ksar、sar及相关内核知识点解析

    关键词:sar.sadc.ksar./proc/stat./proc/cpuinfo./proc/meminfo./proc/diskstats. 在之前有简单介绍过sar/ksar,最近在使用中感觉 ...

  6. 互怼、IPO、雷潮、寒冬,2018 互联网圈的那些事儿

    有了人的地方,就会有江湖. 有江湖的地方,就会有门派. 有门派的地方,就会有纷争. 有纷争的地方,就会有兴衰. 2018年马上就要离我们远去了,迎接我们的将会是新的一年——2019年.在整个过去的20 ...

  7. PS制作漂亮紫色霓虹灯光文字

    一.新建画布,大小1500 * 950像素,分辨率为300,置入墙壁图像,大小适合. 二.调整图层的色阶,色相/饱和度. 三.新建文字图层,颜色为#a33e88,大小为103,字体为Beon Medi ...

  8. C#中的虚函数及继承关系

    转载:http://blog.csdn.net/suncherrydream/article/details/8423991 若一个实例方法声明前带有virtual关键字,那么这个方法就是虚方法. 虚 ...

  9. Spring 使用AOP——xml配置

    目录 AOP介绍 Spring进行2种实现AOP的方式 导入jar包 基于schema-based方式实现AOP 创建前置通知 创建后置通知 修改Spring配置文件 基于schema-based方式 ...

  10. spring boot 表单验证

    1 设置某个字段的取值范围 1.1 取值范围验证:@Min,@Max ① 实例类的属性添加注解@Min ② Controller中传入参数使用@Valid注解 1.2 不能为空验证:@NotNull ...