bmp图像格式详解BMP图像数据格式详解-阿里云开发者社区
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
//LCD 设备参数 : 色深32位 , 分辨率800*480
#include <linux/fb.h> //添加显卡驱动头文件
typedef unsigned short UINT16;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef unsigned int LONG;
//定义位图文件头
typedef struct tagBITMAPFILEHEADER
{
UINT16 bfType; //2Bytes,必须为"BM",即0x424D 才是Windows位图文件
DWORD bfSize; //4Bytes,整个BMP文件的大小
UINT16 bfReserved1; //2Bytes,保留,为0
UINT16 bfReserved2; //2Bytes,保留,为0
DWORD bfOffBits; //4Bytes,文件起始位置到图像像素数据的字节偏移量
}BITMAPFILEHEADER;
//信息头
typedef struct _tagBMP_INFOHEADER
{
DWORD biSize; //4Bytes,INFOHEADER结构体大小,存在其他版本I NFOHEADER,用作区分
LONG biWidth; //4Bytes,图像宽度(以像素为单位)
LONG biHeight; //4Bytes,图像高度,+:图像存储顺序为Bottom2Top,-:Top2Bottom
WORD biPlanes; //2Bytes,图像数据平面,BMP存储RGB数据,因此总为1
WORD biBitCount; //2Bytes,图像像素位数
DWORD biCompression; //4Bytes,0:不压缩,1:RLE8,2:RLE4
DWORD biSizeImage; //4Bytes,4字节对齐的图像数据大小
LONG biXPelsPerMeter; //4 Bytes,用象素/米表示的水平分辨率
LONG biYPelsPerMeter; //4 Bytes,用象素/米表示的垂直分辨率
DWORD biClrUsed; //4 Bytes,实际使用的调色板索引数,0:使用所有的调色板索引
DWORD biClrImportant; //4 Bytes,重要的调色板索引数,0:所有的调色板索引都重要
}BMP_INFOHEADER;
//映射
int (*lcd)[800]=NULL;
//初始化LCD设备
void init_lcd()
{
int lcd_fd = open("/dev/fb0",O_RDWR);
if(lcd_fd < 0)
{
printf("open lcd fail\n");
return ;
}
lcd = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);
close(lcd_fd);
}
//在 sx 和 sy 位置上显示 picname 图片
void show_24bmp(char *picname,int sx,int sy)
{
//1打开图片
int fd = open(picname,O_RDWR);
if(fd<0){puts("open picture fail");return;}
//2读图文件头
BITMAPFILEHEADER head;
read(fd,&head,14);
// 3读信息头
BMP_INFOHEADER msg;
read(fd,&msg,40);
puts(picname);
printf("宽:%d 高:%d 像素:%d\n",msg.biWidth,msg.biHeight,msg.biBitCount);
// 4读图片数据
char rgb[msg.biWidth*msg.biHeight*msg.biBitCount/8];
read(fd,rgb,sizeof(rgb));
// 5 24位像素点转32位像素点
char argb[msg.biWidth*msg.biHeight*4];
for(int i=0;i<msg.biWidth*msg.biHeight;i++)
{
argb[0+4*i]=rgb[0+3*i]; //b
argb[1+4*i]=rgb[1+3*i]; //g
argb[2+4*i]=rgb[2+3*i]; //r
argb[3+4*i]=0; //a
}
// 6 写LCD
//一次写一个像素点,4字节
int (*color)[msg.biWidth] = (void *)argb;
for(int y=0;y<msg.biHeight;y++)
for(int x=0;x<msg.biWidth;x++)
if(y+sy < 480 && x+sx < 800)
lcd[y+sy][x+sx] = color[msg.biHeight-1-y][x];
//关闭图片
close(fd);
}
// ./main 图片
int main(int argc,char *argv[])
{
if(argc!=2){puts("参数错误");return -1;}
//映射
init_lcd();
//显示图片
show_24bmp(argv[1],10,10);
}