BMP2YUV和文件處理的一些想法

0x00

從bmp文件到y(tǒng)uv文件的轉(zhuǎn)換,簡(jiǎn)單的思路分三步:
-從bmp讀取像素信息
-像素信息轉(zhuǎn)換
-寫(xiě)yuv文件

0x01解析bmp

Bmp格式主要以顏色深度區(qū)分(一個(gè)像素占的bit數(shù)),包括單色位圖,16色位圖,256色位圖, 24位真彩色位圖。對(duì)應(yīng)1像素占的bit數(shù)為1bit, 4bit, 8bit, 24bit。
其中單色位圖,16色位圖,256色位圖采用映射的方式來(lái)保存顏色。文件頭中包含顏色表,圖像數(shù)據(jù)指向顏色表,24位位圖無(wú)顏色表,數(shù)據(jù)就是顏色數(shù)值。
bmp起始為文件信息,然后是圖像信息,最后是數(shù)據(jù)。
我們可以直接根據(jù)bmp的固定格式讀取到數(shù)據(jù)。

0x02轉(zhuǎn)換RGB顏色模式為YUV顏色模式

現(xiàn)在我們已經(jīng)獲得了圖像的相關(guān)信息(長(zhǎng),寬,總字節(jié)數(shù)等),和bmp的原始數(shù)據(jù)和顏色表。
每個(gè)像素對(duì)應(yīng)一組RGB, 一組RGB對(duì)應(yīng)一組YUV。由于單色位圖,16色位圖,256色位圖使用數(shù)據(jù)映射顏色表的存儲(chǔ)模式, 即bmp的一個(gè)像素的數(shù)據(jù)代表顏色表中的某一位置的顏色。
直接根據(jù)RGB表建立對(duì)應(yīng)的YUV表, 一個(gè)RGB表項(xiàng)對(duì)應(yīng)一個(gè)yuv表項(xiàng)。則bmp的數(shù)據(jù)可以直接映射YUV表,完成RGB到Y(jié)UV的轉(zhuǎn)化。

0x03寫(xiě)YUV文件

yuv文件包括很多格式, 想用哪個(gè)你就看哪個(gè)吧, 這里就不說(shuō)了。
按數(shù)據(jù)存儲(chǔ)方式分為:packed(YUVYUV), planar(YYUUVV)
按壓縮格式分為:4:4:4,4:2:2, 4:2:0
-444是不壓縮方式, 每個(gè)像素都有一組YUV數(shù)值
-422為第一個(gè)像素采YUV一組值, 第二個(gè)像素只采一個(gè)Y, UV使用前一個(gè)像素的值(這里有點(diǎn)問(wèn)題, 有人說(shuō)是YU, YV,YU, YV這樣采, 兩個(gè)合用一組UV值, 而且行數(shù)必須為偶數(shù),否則會(huì)出現(xiàn)只采到Y(jié)U而沒(méi)有YV。我是采YUV, Y, YUV, Y)
-420依舊是每個(gè)像素都采Y, 第一行的第一二像素和第二行的第一二像素合成一個(gè)方塊,這四個(gè)像素共用一組uv值。(同樣的問(wèn)題:看到有人說(shuō)的是:第一行第一個(gè)像素采U(第一行只采U), 第二行第一個(gè)像素采V(第二行只采V), 第一行第二個(gè)像素, 第二行第二個(gè)像素不采UV。行數(shù)列數(shù)都為偶數(shù), 原因同上。我的做法是:第一行第一個(gè)采YUV,其余三個(gè)只采Y)
然后對(duì)照YUV顏色表把YUV數(shù)據(jù)寫(xiě)到文件就好了。
YUV文件只有數(shù)據(jù), 沒(méi)有信息頭。
我采用的是planar平鋪模式。即先寫(xiě)入所有像素的Y,然后所有的U, 所有的V。

需要注意的坑:

1.bmp的像素?cái)?shù)據(jù)每一行是4字節(jié)對(duì)齊的,不足會(huì)補(bǔ)零,寫(xiě)yuv時(shí)這些補(bǔ)的零都不寫(xiě)
2.用結(jié)構(gòu)體讀取bmp信息頭時(shí)可能出現(xiàn)信息錯(cuò)位,可能原因是編譯器將結(jié)構(gòu)體對(duì)齊優(yōu)化了,#pragma 這個(gè)你自己找找
3.信息頭的值是從1開(kāi)始數(shù)的,如果出現(xiàn)差1那種毛病你懂得
4.bmp的顏色表是Blue, Green,Red順序,別弄錯(cuò)了, 如果用歸一化的轉(zhuǎn)換公式記得想想歸一化是啥意思。
5.bmp文件16進(jìn)制打開(kāi)時(shí)高位在后低位在前,比如7123H在文件中為23H 71H,但是你讀文件讀進(jìn)來(lái)的時(shí)候回自動(dòng)變回7123H
另外,uv=0時(shí),是原諒色,不是無(wú)色

值得提煉的東西:這個(gè)程序雖然實(shí)現(xiàn)了功能,但代碼實(shí)在丑陋, 以后還是要多練。一個(gè)事情分幾步在寫(xiě)之前就該考慮清楚,紙和筆很有幫助。沒(méi)有什么是debug不了了, 講來(lái)講去不過(guò)都是數(shù)字。bmp文件yuv文件16進(jìn)制打開(kāi)和理論對(duì)照一下很快就明白是怎么回事。文件格式理論和實(shí)際互相驗(yàn)證,文件之類再也不是問(wèn)題。一個(gè)問(wèn)題找不到辦法解決時(shí)可能是因?yàn)樘珣辛耍袀€(gè)最苦最累最笨的方法還在那等著。

放個(gè)蠢蠢的github鏈接:https://github.com/ChenDuXiu/BMP2YUV.git

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容