前两天因为要测试的系统的屏幕是16位色的,需要5-6-5格式的位图来进行测试,随手翻了一下电脑上的图片,都是24位的。找了半天竟然没有找到合适的24位转16位的软件。GIMP是找了半天,还是不会用来把24位的转换为16位的。convert命令倒是有个colors参数,但是转出来,8位的还像,但是,一张800×480的图片转了一中午,竟然,查看结果还是24位的。很是郁闷。
想想图片格式转换还不算太难,BMP的格式其实挺简单,对着网上的说明,自己写了一个临时的C程序来完成这个任务。其实关键就是两个文件头的数据结构,一个是文件基本信息,包括了文件类型,大小和位图阵列在文件中的偏移量。而紧接着这个头的是一个具体的位图信息头,其实网上有比较详细的资料比如:和,所以不再赘述。
但是里边还是有细节是我实验得出的,比如,文件头就是类型是’BM’的位图,文件头就是54字节,颜色表或者16位位图的颜色掩码也算在数据里。颜色掩码的分别是三个32位无符号整数,从前到后分别代表红、绿、蓝的分量所占的位。而且24位使用BI_RGB(0)模式存储,除了54字节的文件头外,都是图像数据或者填充。我这次处理的图片不需要处理对齐问题,就没有仔细考虑这个问题,程序中也没有。很重要的一点,这里的多字节数据存储方式都是小端。我是试验出来的~貌似没有地方讲这个问题~而且16位位图的一个像素占两个字节,是一个16位的整数,也是按照小端模式来存储的……谨记之~
顺便传上这个应急程序,连read、write的状态都没有检查……
代码如下:
#include
#include
#include
#include
#include
#include
struct header1 {
unsigned short type;
size_t size;
unsigned short r1;
unsigned short r2;
size_t off;
} __attribute__((packed));
struct header2 {
size_t size;
long width;
long height;
unsigned short planes;
unsigned short bit_count;
unsigned long compression;
size_t img_size;
long x_pels_per_meter;
long y_pels_per_meter;
unsigned long color_used;
unsigned long color_important;
} __attribute__((packed));
struct data16 {
unsigned short r:5;
unsigned short g:6;
unsigned short b:5;
};
int main(int argc, char *argv[])
{
int fd_in, fd_out;
struct header1 in_header1;
struct header2 in_header2;
unsigned char in_buff[3] = {0};
struct data16 out_buff;
size_t i, n;
const unsigned long red_mask = 0xF800ul;
const unsigned long green_mask = 0x07E0ul;
const unsigned long blue_mask = 0x001Ful;
if (argc != 3) {
fprintf(stderr, "Wrong usage!\n"
"Tyr %s
阅读(5414) | 评论(1) | 转发(0) |