本文主要是介绍GEC6818开发板显示BMP格式图片,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1、BMP格式图片
bmp格式图片是没有经过任何压缩过的图片,缺点是为文件尺寸比较大,不适合传播;优点是文件必须要解码器可以读出来直接使用。
虽然BMP格式文件内部存储的就是RGB数据,无需任何解码,但毕竟RGB数据是纯数据,没有任何图片尺寸、色深等具体信息,因此我们需要了解BMP的格式头,在BMP格式头中获取图片的相关信息,然后才能正确处理内涵的RGB数据。
2、BMP格式头
BMP文件开头部分是BMP格式头,里面存放了RGB数据的尺寸、分辨率、色深等重要信息。BMP格式头中包含了如下三个结构体:
- bitmap_header(必有)
- bitmap_info(必有)
- rgb_quad(可选,一般没有)
struct bitmap_header
{int16_t type;int32_t size; // 图像文件大小int16_t reserved1;int16_t reserved2;int32_t offbits; // bmp图像数据偏移量
}__attribute__((packed));struct bitmap_info
{int32_t size; // 本结构大小 int32_t width; // 图像宽int32_t height; // 图像高int16_t planes;int16_t bit_count; // 色深int32_t compression;int32_t size_img; // bmp数据大小,必须是4的整数倍int32_t X_pel;int32_t Y_pel;int32_t clrused;int32_t clrImportant;
}__attribute__((packed));// 以下结构体不一定存在于BMP文件中,除非:
// bitmap_info.compression为真
struct rgb_quad
{int8_t blue;int8_t green;int8_t red;int8_t reserved;
}__attribute__((packed));
- 上下颠倒
BMP图片中的RGB数据是上下颠倒的,因此文件数据中的最后一行是图像的最上面第一行。需要注意的是,上下是颠倒的,但是左右是正常的,因此在处理数据的时候不能从最后一个字节开始,而是从最末一行的首字节开始。
3、获取bmp图片信息及显示示例代码:
struct bitmap_header
{int16_t type;int32_t size; // 图像文件大小int16_t reserved1;int16_t reserved2;int32_t offbits; // bmp图像数据偏移量
}__attribute__((packed));struct bitmap_info
{int32_t size; // 本结构大小 int32_t width; // 图像宽int32_t height; // 图像高int16_t planes;int16_t bit_count; // 色深int32_t compression;int32_t size_img; // bmp数据大小,必须是4的整数倍int32_t X_pel;int32_t Y_pel;int32_t clrused;int32_t clrImportant;
}__attribute__((packed));// 以下结构体不一定存在于BMP文件中,除非:
// bitmap_info.compression为真
struct rgb_quad
{int8_t blue;int8_t green;int8_t red;int8_t reserved;
}__attribute__((packed));struct bmp
{uint32_t size; //RGB数据大小uint32_t w; //图像宽度uint32_t h; //图像高度uint8_t *data; //图像RGB数据
};void read_bmp_data(const char *pathname, struct bmp *p)
{/******************获取BMP文件数据**********************/FILE *bmp_file = fopen(pathname, "r");if(bmp_file){//读BMP图片属性信息struct bitmap_header file_header; //文件头struct bitmap_info info_header; //信息头fread(&file_header, sizeof file_header, 1, bmp_file);fread(&info_header, sizeof info_header, 1, bmp_file);p->w = info_header.width;p->h = info_header.height;p->size = info_header.size_img;// 读取BMP图像数据(RGB)p->data = calloc(1, info_header.size_img);fread(p->data, info_header.size_img, 1, bmp_file);fclose(bmp_file);}else{printf("打开%s文件失败: %s\n", pathname, strerror(errno));}
}//uint32_t x,uint32_t y为图片坐标
void display_bmp(struct lcd lcd, const char *pathname, uint32_t x, uint32_t y)
{struct bmp tmp;read_bmp_data(pathname, &tmp);int color;// 画图像for (int i = 0; i < tmp.h; i++){for(int j = 0; j < tmp.w; j++){color = tmp.data[((tmp.h-1-i)*tmp.w+j)*3] | //Btmp.data[((tmp.h-1-i)*tmp.w+j)*3+1]<<8 | //Gtmp.data[((tmp.h-1-i)*tmp.w+j)*3+2]<<16 | //R0x00<<24; //ADraw_point(lcd, color, j+x, i+y); //Draw_point()为在LCD上画点 }}free(tmp.data);
}
这篇关于GEC6818开发板显示BMP格式图片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!