电子相册(BMP图像文件的解析)

首先,我们应该对BMP文件的格式有了解。

       BMP(全称Bitmap)是Windows操作系统中的标准图像文件格式,使用非常广,并采用位映射存储格式。

       最常见的就是24位图,也称真彩色,就是说一个像素的颜色信息用24位来表示。对于三原色BRG,每一个颜色都用以字节(8 bit)来表示,颜色顺序为BGR。

      除了24位图,还有1位(单色),2位(4色,CGA),4位(16色,VGA),8位(256色),16位(增强色)和32位(BGRA)等。

BMP格式的文件从头到尾依次是如下信息:
        bmp文件头(bmp file header):共14字节;
        位图信息头(bitmap information):共40字节;
        调色板(color palette):可选;
        像素数组;

1.判断是否位BMP文件

lseek(fd, 0x0, SEEK_SET);//fd为打开的图片文件,lseek移动光标到文件开头
read(fd, buf, 2);//读出信息到一个大小为2字节的buf里
if((buf[0] != 0x42) || (buf[1] != 0x4D)) //文件开头的两个字节必须是0x42, 0x4D
{
	printf("It is not bmp format file\n");
	return;	
}

参考如下表: 

电子相册(BMP图像文件的解析)_第1张图片图片文件头信息参考

2. 解析出BMP文件的相关信息

      宽(width),高(height),深度(depth)。

width =	 (buf[0] & 0xFF) | 
	 (( buf[1] & 0xFF) << 8) |
         (( buf[2] & 0xFF) << 16) | 
         (( buf[3] & 0xFF) << 24);
lseek(fd, 0x16, SEEK_SET);
read(fd, buf, 4);
	
height = (buf[0] & 0xFF) | 
	 ((buf[1] & 0xFF) << 8 ) |
         ((buf[2] & 0xFF) << 16) | 
         ((buf[3] & 0xFF) << 24);
lseek(fd, 0x1C, SEEK_SET);
	
read(fd, buf, 2);
depth =	(buf[0] & 0xFF) | 
	((buf[1] & 0xFF) << 8);
//size表示图像真正的像素数据
size = abs(width*height*depth/8);//height有可能是负数

 参考如下表:

电子相册(BMP图像文件的解析)_第2张图片参考表

3.解析出每个像素点的信息 

//pixel用于保存像素信息
pixel = (unsigned char *) malloc (size *sizeof(unsigned char));
lseek(fd, 54, SEEK_SET); //真正的像素信息在54个字节的偏移量
read(fd, pixel, size);	

int x, y;//(x, y)表示当前从pixel取颜色的坐标
unsigned char r, g, b, a;
int i = 0, real_y; //real_y表示屏幕的坐标
int color; //因为屏幕的每个像素是32bit
for(y = 0; y < abs(height); y++)
{
	for(x = 0;x < abs(width);x++)
	{
	//b, g, r的顺序是按bmp格式要求
		b = (pixel[i++] & 0xFF);
		g = (pixel[i++] & 0xFF);
		r = (pixel[i++] & 0xFF);
		if(32 == depth) //depth是图片的深度
			a = (pixel[i++] & 0xFF);
		else//depth为24
			a = 0x0;
		color = (a<<24) | (r<<16) | (g<<8) | b;
		if(height > 0) //height为正的时候,表示存储的第一行是要显示到屏幕上的最后一行
			real_y = height -1 - y;
		else
			real_y = y;
		//Draw_Point( x, real_y, color);
	}
}
free(pixel);//free掉malloc到的存储空间能防止内存泄漏

      Draw_Point( x, real_y, color)为我自定义的描点函数,通过交叉编译最终可在开发板上显示图片。

你可能感兴趣的:(电子相册)