本文介紹BMP 轉(zhuǎn) YUV,。其實(shí)這是以前“數(shù)據(jù)壓縮”實(shí)驗(yàn)課上的內(nèi)容,前幾天有人問我相關(guān)的問題,,突然發(fā)現(xiàn)自己有一段時(shí)間沒有接觸BMP也有些生疏了,,因此翻出資料總結(jié)一下。
BMP文件格式解析
位圖文件(Bitmap-File,BMP)格式是Windows采用的圖像文件存儲格式,,在Windows環(huán)境下運(yùn)行的所有圖像處理軟件都支持這種格式,。BMP位圖文件默認(rèn)的文件擴(kuò)展名是bmp或者dib。BMP文件大體上分為四個部分:
位圖文件頭主要包括:
- typedef struct tagBITMAPFILEHEADER {
- WORD bfType; /* 說明文件的類型 */
- DWORD bfSize; /* 說明文件的大小,,用字節(jié)為單位 */
- WORD bfReserved1; /* 保留,,設(shè)置為0 */
- WORD bfReserved2; /* 保留,設(shè)置為0 */
- DWORD bfOffBits; /* 說明從BITMAPFILEHEADER結(jié)構(gòu)開始到實(shí)際的圖像數(shù)據(jù)之間的字節(jié)偏移量 */
- } BITMAPFILEHEADER;
位圖信息頭主要包括:
- typedef struct tagBITMAPINFOHEADER {
- DWORD biSize; /* 說明結(jié)構(gòu)體所需字節(jié)數(shù) */
- LONG biWidth; /* 以像素為單位說明圖像的寬度 */
- LONG biHeight; /* 以像素為單位說明圖像的高速 */
- WORD biPlanes; /* 說明位面數(shù),,必須為1 */
- WORD biBitCount; /* 說明位數(shù)/像素,,1、2,、4,、8、24 */
- DWORD biCompression; /* 說明圖像是否壓縮及壓縮類型BI_RGB,,BI_RLE8,,BI_RLE4,BI_BITFIELDS */
- DWORD biSizeImage; /* 以字節(jié)為單位說明圖像大小,,必須是4的整數(shù)倍*/
- LONG biXPelsPerMeter; /*目標(biāo)設(shè)備的水平分辨率,,像素/米 */
- LONG biYPelsPerMeter; /*目標(biāo)設(shè)備的垂直分辨率,像素/米 */
- DWORD biClrUsed; /* 說明圖像實(shí)際用到的顏色數(shù),,如果為0,,則顏色數(shù)為2的biBitCount次方 */
- DWORD biClrImportant; /*說明對圖像顯示有重要影響的顏色索引的數(shù)目,如果是0,,表示都重要,。*/
- } BITMAPINFOHEADER;
調(diào)色板實(shí)際上是一個數(shù)組,它所包含的元素與位圖所具有的顏色數(shù)相同,,決定于biClrUsed和biBitCount字段,。數(shù)組中每個元素的類型是一個RGBQUAD結(jié)構(gòu)。真彩色無調(diào)色板部分,。
- typedef struct tagRGBQUAD {
- BYTE rgbBlue; /*指定藍(lán)色分量*/
- BYTE rgbGreen; /*指定綠色分量*/
- BYTE rgbRed; /*指定紅色分量*/
- BYTE rgbReserved; /*保留,,指定為0*/
- } RGBQUAD;
緊跟在調(diào)色板之后的是圖像數(shù)據(jù)字節(jié)陣列。對于用到調(diào)色板的位圖,,圖像數(shù)據(jù)就是該像素顏色在調(diào)色板中的索引值(邏輯色),。對于真彩色圖,圖像數(shù)據(jù)就是實(shí)際的R,、G,、B值。圖像的每一掃描行由表示圖像像素的連續(xù)的字節(jié)組成,,每一行的字節(jié)數(shù)取決于圖像的顏色數(shù)目和用像素表示的圖像寬度,。規(guī)定每一掃描行的字節(jié)數(shù)必需是4的整倍數(shù),,也就是DWORD對齊的。掃描行是由底向上存儲的,,這就是說,,陣列中的第一個字節(jié)表示位圖左下角的像素,而最后一個字節(jié)表示位圖右上角的像素,。
讀取BMP文件,,提取RGB數(shù)據(jù)的流程
流程如下圖所示:
在這里需要注意的的是,根據(jù)BMP每像素所占的比特?cái)?shù)不同(8,,16,,32 bpp),分為不同的處理方法,,如下圖所示,。
下面看看16bpp的BMP文件操作:
R,G,B在16bit中所占的位數(shù)如下圖所示
- for (Loop = 0;Loop < height * width;Loop +=2)
- {
- *rgbDataOut = (Data[Loop]&0x1F)<<3;
- *(rgbDataOut + 1) = ((Data[Loop]&0xE0)>>2) + ((Data[Loop+1]&0x03)<<6);
- *(rgbDataOut + 2) = (Data[Loop+1]&0x7C)<<1;
- rgbDataOut +=3;
- }
1-8bpp的BMP文件操作:- int shiftCnt = 1;
- while (mask)
- {
- unsigned char index = mask == 0xFF ? Data[Loop] : ((Data[Loop] & mask)>>(8 - shiftCnt * info_h.biBitCount));
- * rgbDataOut = pRGB[index].rgbBlue;
- * (rgbDataOut+1) = pRGB[index].rgbGreen;
- * (rgbDataOut+2) = pRGB[index].rgbRed;
- if(info_h.biBitCount == 8) mask = 0;
- Else mask >>= info_h.biBitCount;
- rgbDataOut+=3;
- shiftCnt ++;
- }
BMP轉(zhuǎn)換為YUV
RGB到色差信號的轉(zhuǎn)換如下所示:
Y=0.2990R+0.5870G+0.1140B
R-Y=0.7010R-0.5870G-0.1140B
B-Y=-0.2990R-0.5870G+0.8860B
為了使色差信號的動態(tài)范圍控制在0.5之間,需要進(jìn)行歸一化,,對色差信號引入壓縮系數(shù),。歸一化后的色差信號為:
U=-0.1684R-0.3316G+0.5B
V=0.5R-0.4187G-0.0813B
YUV文件的格式
轉(zhuǎn)換后的YUV數(shù)據(jù)需要存成YUV文件(在這里是YUV420P格式)。YUV文件的格式很簡單,,先連續(xù)存Y,,然后U,然后V,,如圖所示,。
BMP 轉(zhuǎn) YUV程序下載地址:http://download.csdn.net/detail/leixiaohua1020/6469807
|