一、前言
用X86 PC的画图软件打开该文件如下,可以看到是一些颜色渐变的过程,目的就是要把每个颜色等级的数据提取出来。 笔者的思路是把pal文件用X86 PC(Win7和Win10)的画图软件分别保存了24bit BMP格式的位图(其他位的位图没研究过),Win7系统保存完之后如下(Win10同样): 查看这张位图的属性,可以看到一共256个颜色等级,每个等级的颜色宽度为25。satagr_win7为Win7系统保存出来的图片(19K,颜色深度24位)。笔者在Win10系统上也用画图软件也存了一张24Bit的位图,有趣的是与Win7系统转换的位图不一样,satagr_win10为Win10系统用画图软件保存出来的位图(25K,和原始的pal文件一样大,颜色深度32位)。猜想是买个不同操作系统的画图软件编码bmp的实现不一样吧。
红色框的是最后一个颜色的数据,Win7的颜色深度为24BIt,所以每个像素点颜色BGR每个颜色分量占用一个字节,而每行的颜色以00结束,所以每行的数据为25*3+1个字节大小;而Win10的颜色深度为32Bit,所以每个像素点颜色BGR占用4个字节,没个像素点以BGR的每个分量+FF,每个数据为BGR+FF(00 00 00 FF),在在画图软件中我们可以看到该颜色刚好为位图的最后一个颜色(黑色):
所以数据的排列是BGR+FF,同时位图的最开始的颜色数据在文件的最后,因为把这50、10、250三个数据随便怎么调换,只有上图的顺序才是红色。文件数据的格式我们已经知道了,下面就是编写程序提取24Bit 位图数据为RGB数据; 二、程序源码的分享
unsigned char* bmpBuf; bmpBuf = (char*)malloc(BMP_SIZE); if(bmpBuf == NULL){ printf('failed to allocate buff_in_bmp %s, %d\n', __FILE__, __LINE__); return -1; }
int src_fd = open(INPUT_BMP_PATH, O_RDONLY ); if( -1 == src_fd ) { printf('++++++open file failed %s,%d\n', __FILE__, __LINE__); return -1; } int read_size = read( src_fd, bmpBuf, BMP_SIZE); 2、把每行对应的颜色提取成RGB数据,并以文本来保存。注意:①Win7和Win10不同的数据排版,对我们提取并没有影响,只要按照对应格式提取就行;②位图中颜色分量的数据排列顺序是以BGR排列的;③换行符在Linux和Window系统显示是有区别的
即在Linux输出文本的换行符用
即在Windows输出文本的换行符用
保存出来的文本形式如下:
3、把对应的RGB数据保存为YVU数据分量的文本,其中RGB转YVU的公式度娘上大把: FILE *fpYuv; unsigned char y , u, v, r, g, b; if((fpYuv = fopen(OUTPUT_YUV_PATH,'w')) == NULL){ printf('cannot open this file %s, %d\n', __FILE__, __LINE__); return -1; } for(i = 0; i< 256; i++){ r = bmpBuf[54+i*BMP_PER_LINE_BYTE+2]; g = bmpBuf[54+i*BMP_PER_LINE_BYTE+1]; b = bmpBuf[54+i*BMP_PER_LINE_BYTE]; y = ((77*r+150*g+29*b)>>8); u = ((-43*r-85*g+128*b)>>8)+128; v = ((128*r-107*g-21*b)>>8)+128; sprintf(str,'\{%d, %d, %d\}\,',y,u,v); if(fputs(str,fpYuv) == '\0'){ printf('cannot open file %s, %d\n', __FILE__, __LINE__); return -1; } #ifdef LINUX fputs('\n',fpYuv); #else fputs('\r\n',fpYuv); #endif } fclose(fpYuv); |
|
来自: 西北望msm66g9f > 《培训》