2012.07.06 保存bin数据为bmp文件

bmp文件有着自己的文件头:

 

BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息。

位图文件主要分为如下3个部分:

块名称

对应Windows结构体定义

大小(Byte

文件信息头

BITMAPFILEHEADER

14

位图信息头

BITMAPINFOHEADER

 

40

RGB颜色阵列

BYTE*

由图像长宽尺寸决定

1   文件信息头BITMAPFILEHEADER

结构体定义如下:

typedef struct tagBITMAPFILEHEADER {

WORD  bfType;  
DWORD bfSize; 
WORD  bfReserved1;
 
WORD  bfReserved2;
 
DWORD bfOffBits;

} BITMAPFILEHEADER;

其中:??

bfType<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

说明文件的类型,该值必需是0x4D42,也就是字符'BM'

bfSize

说明该位图文件的大小,用字节为单位

bfReserved1

保留,必须设置为0

bfReserved2

保留,必须设置为0

bfOffBits

说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据。

 

2位图信息头BITMAPINFOHEADER

结构体定义如下:

typedef struct tagBITMAPINFOHEADER {

DWORD biSize; 
LONG biWidth;
 
LONG biHeight;
 
WORD biPlanes;
 
WORD biBitCount;
 
DWORD biCompression;
 
DWORD biSizeImage;
 
LONG biXPelsPerMeter;
 
LONG biYPelsPerMeter;
 
DWORD biClrUsed;
 
DWORD biClrImportant;

} BITMAPINFOHEADER;

其中:

biSize

说明BITMAPINFOHEADER结构所需要的字数。

biWidth

说明图象的宽度,以象素为单位。

biHeight

说明图象的高度,以象素为单位。注:这个值除了用于描述图像的高度之外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明图像是倒向的,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也就是时,高度值是一个正数。

biPlanes

为目标设备说明位面数,其值将总是被设为1

biBitCount

说明比特数/象素,其值为1481624、或32。但是由于我们平时用到的图像绝大部分是24位和32位的,所以我们讨论这两类图像。

biCompression

说明图象数据压缩的类型,同样我们只讨论没有压缩的类型:BI_RGB

biSizeImage

说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0

biXPelsPerMeter

说明水平分辨率,用象素/米表示。

biYPelsPerMeter

说明垂直分辨率,用象素/米表示。

biClrUsed

说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。

biClrImportant

说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。

 具体数据举例:

如某BMP文件开头:
424D 4690 0000 0000 0000 4600 0000 2800 0000 8000 0000 9000 0000 0100*1000 0300 0000 0090 0000 A00F 0000 A00F 0000 0000 0000 0000 0000*00F8 0000 E007 0000 1F00 0000 0000 0000*02F1 84F1 04F1 84F1 84F1 06F2 84F1 06F2 04F2 86F2 06F2 86F2 86F2 .... .... 
BMP文件可分为四个部分:位图文件头、位图信息头、彩色板、图像数据阵列,在上图中已用*分隔。
一、图像文件头
1)1:(这里的数字代表的是"字",即两个字节,下同)图像文件头。424Dh=’BM’,表示是Windows支持的BMP格式。
2)2-3:整个文件大小。4690 0000,为00009046h=36934。
3)4-5:保留,必须设置为0。
4)6-7:从文件开始到位图数据之间的偏移量。4600 0000,为00000046h=70,上面的文件头就是35字=70字节。
5)8-9:位图图信息头长度。
6)10-11:位图宽度,以像素为单位。8000 0000,为00000080h=128。
7)12-13:位图高度,以像素为单位。9000 0000,为00000090h=144。
8)14:位图的位面数,该值总是1。0100,为0001h=1。
二、位图信息头
9)15:每个像素的位数。有1(单色),4(16色),8(256色),16(64K色,高彩色),24(16M色,真彩色),32(4096M色,增强型真彩色)。1000为0010h=16。
10)16-17:压缩说明:有0(不压缩),1(RLE 8,8位RLE压缩),2(RLE 4,4位RLE压缩,3(Bitfields,位域存放)。RLE简单地说是采用像素数+像素值的方式进行压缩。T408采用的是位域存放方式,用两个字节表示一个像素,位域分配为r5b6g5。图中0300 0000为00000003h=3。
11)18-19:用字节数表示的位图数据的大小,该数必须是4的倍数,数值上等于位图宽度×位图高度×每个像素位数。0090 0000为00009000h=80×90×2h=36864。
12)20-21:用象素/米表示的水平分辨率。A00F 0000为0000 0FA0h=4000。
13)22-23:用象素/米表示的垂直分辨率。A00F 0000为0000 0FA0h=4000。
14)24-25:位图使用的颜色索引数。设为0的话,则说明使用所有调色板项。
15)26-27:对图象显示有重要影响的颜色索引的数目。如果是0,表示都重要。

如果要是只对纯的bin文件添加头只需要定义上面你的结构,按照固定的格式先写文件头,再把文件写进去;这里值得注意的是: bmp文件的显示方式是从左下角开始到右上角结束,所以在写文件的时候不能直接把bin数据加入,而是要从下往上逐行写入:

                                     int pixl = width * sizeof(short);

                                     for(i=height;i>0;i--)

                                          int temp=write(fd,buff+(i-1)*pixl,pixl);

其中pixl是每行的字节数,列数乘以每列的字节, 从下往上逐行写入。

 

而当bin数据里面包含有头的时候,比如几张bmp图片的bin数据存放到一起,要从里面分离开,写成单独的bmp文件:

做之前首先要知道几个函数的用法:

1open()函数:

  定义函数

  int open( const char * pathname,int flags);

  int open( const char * pathname,int flags,mode_t mode);

函数说明

  参数pathname 指向欲打开的文件路径字符串。下列是参数flags 所能使用的标志位

  O_RDONLY 以只读方式打开文件

  O_WRONLY 以只写方式打开文件

  O_RDWR 以可读写方式打开文件。

  上述三种标志位是互斥的,也就是不可同时使用,但可与下列的标志位利用OR(|)运算符组合。

  O_CREAT 若欲打开的文件不存在则自动建立该文件。

 

2 read()函数

定义函数

  ssize_t read(int fd,void * buf ,size_t count);

  函数说明

  read()会把参数fd 所指的文件传送count个字节到buf指针所指的内存中。若参数count为0,则read为实际读取到的字节数,如果返回0,表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动。

3write()函数

定义函数

  ssize_t write (int fd,const void * buf,size_t count);

函数说明

  write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。当然,文件读写位置也会随之移动。

他们包含的表头文件为:

 #include<unistd.h>

4、amlloc()函数

void *malloc(size_t size);

  说明:malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。

 

5、

main函数参数的用法

main函数参数的用法

main函数的声明
int main(int argc, char **argv)
或者
int main(int argc, char *argv[])
依据《C程序设计语言(第二版.新版)》的讲述:
第一个参数(习惯上称为argc,用于参数计数)的值表示运行程序时,命令行中参数的数目;
第二个参数(称为argv,用于参数的向量)是一个指向字符串数组的指针,其中每个字符串对应一个参数。

例子是在命令行模式下,在命令提示符$后输入:
$ echo hello,world
则会显示:
hello,world
$ (提示符,等待输入命令)

下面用C语言实现这个echo的程序:

//使用书中的第一个版本程序,文件名保存为 echo.c
#include <stdio.h>
/* echo command-line arguments; 1st version */
int main(int argc, char *argv[])
{
   int i;
   for (i = 1; i < argc; i++)
       printf("%s%s", argv[i], (i < argc-1) ? " " : "");
   printf("\n");
   return 0;
}
//编译,运行,结果什么也没有。

令行参数,进入到编译后产生可执行 echo 文件的目录,然后在命令提示符后输入:
$ ./echo hello,world
程序就会运行出来结果:
hello,word
$ (提示符,等待输入命令)

C语言约定:argv[0]的值是启动该程序的程序名,因此argc的值至少为1。
如果argc的值是1,说明程序名后面没有命令行参数。

另外还要提一个就是字节对齐,这里非常的重要,如果不把字节对齐很容易使得bmp头格式不对

 

字节对齐概念:

#pragma pack()

  结构体代码

#pragma pack()

 

主要思想就是:

1、从给的bin文件中读出bmp的文件信息头信息:

bfType<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

说明文件的类型,该值必需是0x4D42,也就是字符'BM'

bfSize

说明该位图文件的大小,用字节为单位

bfReserved1

保留,必须设置为0

bfReserved2

保留,必须设置为0

bfOffBits

说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据。

 

       然后将其写入buff中,在从文件信息头里读取该bmp文件的大小以及数据的偏移地址,就可以将剩下的数据部分读入刚才的buff,最后将buff中的内容写入bmp文件中即可;

       一词循环就可以将所有的文件写出来了;具体程序代码就省略了;有需要的M;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值