一、前言
用X86 PC的畫圖軟件打開該文件如下,可以看到是一些顏色漸變的過程,目的就是要把每個顏色等級的數(shù)據(jù)提取出來。 筆者的思路是把pal文件用X86 PC(Win7和Win10)的畫圖軟件分別保存了24bit BMP格式的位圖(其他位的位圖沒研究過),Win7系統(tǒng)保存完之后如下(Win10同樣): 查看這張位圖的屬性,可以看到一共256個顏色等級,每個等級的顏色寬度為25。satagr_win7為Win7系統(tǒng)保存出來的圖片(19K,顏色深度24位)。筆者在Win10系統(tǒng)上也用畫圖軟件也存了一張24Bit的位圖,有趣的是與Win7系統(tǒng)轉(zhuǎn)換的位圖不一樣,satagr_win10為Win10系統(tǒng)用畫圖軟件保存出來的位圖(25K,和原始的pal文件一樣大,顏色深度32位)。猜想是買個不同操作系統(tǒng)的畫圖軟件編碼bmp的實現(xiàn)不一樣吧。
紅色框的是最后一個顏色的數(shù)據(jù),Win7的顏色深度為24BIt,所以每個像素點顏色BGR每個顏色分量占用一個字節(jié),而每行的顏色以00結(jié)束,所以每行的數(shù)據(jù)為25*3+1個字節(jié)大?。欢鳺in10的顏色深度為32Bit,所以每個像素點顏色BGR占用4個字節(jié),沒個像素點以BGR的每個分量+FF,每個數(shù)據(jù)為BGR+FF(00 00 00 FF),在在畫圖軟件中我們可以看到該顏色剛好為位圖的最后一個顏色(黑色):
所以數(shù)據(jù)的排列是BGR+FF,同時位圖的最開始的顏色數(shù)據(jù)在文件的最后,因為把這50、10、250三個數(shù)據(jù)隨便怎么調(diào)換,只有上圖的順序才是紅色。文件數(shù)據(jù)的格式我們已經(jīng)知道了,下面就是編寫程序提取24Bit 位圖數(shù)據(jù)為RGB數(shù)據(jù); 二、程序源碼的分享
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、把每行對應(yīng)的顏色提取成RGB數(shù)據(jù),并以文本來保存。注意:①Win7和Win10不同的數(shù)據(jù)排版,對我們提取并沒有影響,只要按照對應(yīng)格式提取就行;②位圖中顏色分量的數(shù)據(jù)排列順序是以BGR排列的;③換行符在Linux和Window系統(tǒng)顯示是有區(qū)別的
即在Linux輸出文本的換行符用
即在Windows輸出文本的換行符用
保存出來的文本形式如下:
3、把對應(yīng)的RGB數(shù)據(jù)保存為YVU數(shù)據(jù)分量的文本,其中RGB轉(zhuǎn)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 > 《培訓(xùn)》