BMP格式的图片的介绍,和头信息的解析:
https://www.cnblogs.com/l2rf/p/5643352.html
重要结构体:
从BMP文件中读到的头信息:(这些信息只是取了部分信息)
/* bmp 头信息 */
struct bmp_head_data
{
unsigned short w; /* 图片宽 */
unsigned short h; /* 图片高 */
unsigned int picture_size; /* 图片总的大小(包括头信息) */
unsigned int data_size; /* 图片的有效数据信息 */
};
重要函数:
下面的绝对和相对的概念:
如:fb_bmp_180_show
不是当前的图片旋转180,因为当前图片可能向左,可能向右,底层的不想知道图片现在是怎样显示,它只需要对文件的数据进行不同的读取而达到旋转180,因为文件的数据是不会变的。
上层显示函数:
/* bmp 显示的核心函数 */
void fb_show_bmp(struct show_picture_set *set)
{
struct bmp_head_data *st_pi = malloc(sizeof(struct bmp_head_data));
const char *p_path = set->path;
fb_file_to_bmp(p_path, st_pi); /* 从bmp文件中读头信息 */
fb_bmp_read_file(p_path, st_pi); /* 从文件中读有效数据到 now_picture 中 */
//fb_draw_back(WIDTH, HEIGHT, WHITE); //把背景变为白色
switch (set->rotate){
case ROTATE_FRONT:
fb_bmp_front_show(set, st_pi); /* bmp 图片正方向显示 */
break;
case ROTATE_180:
fb_bmp_180_show(set, st_pi); /* bmp 图片旋转180方向显示 */
break;
case ROTATE_MIRROR_180:
fb_bmp_mirror_180_show(set, st_pi);
break;
case ROTATE_MIRROR:
fb_bmp_mirror_show(set, st_pi);
break;
}
free(st_pi);
}
BMP判断函数:
/* 判断是否为 bmp 文件*/
char fb_is_bmp(const char *path)
{
int ret;
int fd = -1;
char picture[2];
if ((fd = open(path, O_RDWR)) < 0 ){
DERROR("NO [%s] file", path);
return 'O';
}
if ((ret = read(fd, picture, 2)) < 2){
DERROR("read [%s] file error", path);
close(fd);
return 'R';
}
if((picture[0] != 'B') || (picture[1] != 'M')){ /*判断能前两给字节是否是 BM */
DERROR("It's not a BMP file");
close(fd);
return 'N';
}else{
close(fd);
return 'Y';
}
}
从bmp文件中读头信息:
/* 从bmp文件中读头信息 */
int fb_file_to_bmp(const char *path, void *st_pi)
{
int ret;
int fd = -1;
char picture[54]; /* BMP 文件头信息为54字节 */
struct bmp_head_data *hand_data = st_pi;
if ((fd = open(path, O_RDWR)) < 0 ){
DERROR("NO [%s] file", path);
return -1;
}
if ((ret = read(fd, picture, 54)) < 54){
DERROR("read 54 byte [%s] file error", path);
return -1;
}
hand_data->picture_size = *(unsigned int *)(picture + 0x02);
hand_data->w = *(unsigned int *)(picture + 0x12);
hand_data->h = *(unsigned int *)(picture + 0x16);
hand_data->data_size = *(unsigned int *)(picture + 0x22);
close(fd);
return 0;
}
从文件中读有效数据到 now_picture 中:
/* 从文件中读有效数据到 now_picture 中*/
int fb_bmp_read_file(const char *path, struct bmp_head_data *head_data)
{
int ret;
int fd = -1;
if ((fd = open(path, O_RDWR)) < 0 ){
DERROR("NO [%s] file", path);
return -1;
}
lseek(fd, 54, SEEK_SET);
if ((ret = read(fd, now_picture, head_data->data_size)) < head_data->data_size){
DERROR("read [%d] byte [%s] file error", head_data->data_size, path);
return -1;
}
close(fd);
return 0;
}
bmp 图片正方向显示:
/* bmp 图片正方向显示 */
void fb_bmp_front_show(struct show_picture_set *set, struct bmp_head_data *head_data)
{
int x, y;
unsigned int cont1 = 0, cont2 = 0;
unsigned int *p_data = pfb;
for(y = 0; y < head_data->h; y++)
{
if((y + set->h) >= HEIGHT)
break;
for(x = 0; x < head_data->w; x++)
{
if((x + set->w) >= WIDTH){
cont1 += 3;
continue;
}
cont2 = (y + set->h) * WIDTH + x + set->w;
*(p_data + cont2) = ((now_picture[cont1 + 0] << 0) | (now_picture[cont1 + 1] << 8) | (now_picture[cont1 + 2] << 16));
cont1 += 3;
}
}
}
bmp 图片旋转180方向显示 (不是当前图片旋转 180,是绝对而不是相对):
/* bmp 图片旋转180方向显示 (不是当前图片旋转 180,是绝对而不是相对)*/
void fb_bmp_180_show(struct show_picture_set *set, struct bmp_head_data *head_data)
{
int x, y;
unsigned int cont2 = 0, cont1 = ((head_data->h * head_data->w * 3) - 3);
unsigned int *p_data = pfb;
for(y = 0; y < head_data->h; y++)
{
if((y + set->h) >= HEIGHT)
break;
for(x = 0; x < head_data->w; x++)
{
if((x + set->w) >= WIDTH){
cont1 -= 3;
continue;
}
cont2 = (y + set->h) * WIDTH + x + set->w;
*(p_data + cont2) = ((now_picture[cont1 + 0] << 0) | (now_picture[cont1 + 1] << 8) | (now_picture[cont1 + 2] << 16));
cont1 -= 3;
}
}
}
bmp 图片 ( 镜像翻转 + 旋转180方向 )显示 (不是当前图片旋转 180,是绝对而不是相对):
/* bmp 图片 ( 镜像翻转 + 旋转180方向 )显示 (不是当前图片旋转 180,是绝对而不是相对)*/
void fb_bmp_mirror_180_show(struct show_picture_set *set, struct bmp_head_data *head_data)
{
int x, y;
unsigned int cont2 = 0, cont1 = ((head_data->h * head_data->w * 3) - 3);
unsigned int *p_data = pfb;
for(y = 0; y < head_data->h; y++)
{
if((y + set->h) >= HEIGHT)
break;
for(x = head_data->w -1 ; x >= 0; x--)
{
if((x + set->w) >= WIDTH){
cont1 -= 3;
continue;
}
cont2 = (y + set->h) * WIDTH + x + set->w;
*(p_data + cont2) = ((now_picture[cont1 + 0] << 0) | (now_picture[cont1 + 1] << 8) | (now_picture[cont1 + 2] << 16));
cont1 -= 3;
}
}
}
bmp 图片 ( 镜像翻转 )显示 (不是当前图片翻转,是绝对而不是相对):
/* bmp 图片 ( 镜像翻转 )显示 (不是当前图片翻转,是绝对而不是相对)*/
void fb_bmp_mirror_show(struct show_picture_set *set, struct bmp_head_data *head_data)
{
int x, y;
unsigned int cont2 = 0, cont1 = 0;
unsigned int *p_data = pfb;
for(y = 0; y < head_data->h; y++)
{
if((y + set->h) >= HEIGHT)
break;
for(x = head_data->w -1 ; x >= 0; x--)
{
if((x + set->w) >= WIDTH){
cont1 += 3;
continue;
}
cont2 = (y + set->h) * WIDTH + x + set->w;
*(p_data + cont2) = ((now_picture[cont1 + 0] << 0) | (now_picture[cont1 + 1] << 8) | (now_picture[cont1 + 2] << 16));
cont1 += 3;
}
}
}