Camera YUV 圖片格式轉(zhuǎn)換和畫(huà)面旋轉(zhuǎn)的問(wèn)題

Camera YUV 圖片格式轉(zhuǎn)換和畫(huà)面旋轉(zhuǎn)的問(wèn)題

YUV 格式

Camera 拍照方向與預(yù)覽的問(wèn)題

YUV 轉(zhuǎn) RGB 的轉(zhuǎn)換矩陣
橫屏拍照到預(yù)覽效果

前面介紹 YUV 格式和 Camera 的方向問(wèn)題代乃,就是為了這一個(gè)做準(zhǔn)備的垮耳。

遇到的問(wèn)題:

  • Camera 拿到的幀都是 YUV 格式的。
  • 一些圖片處理算法需要基于 RGB 圖片進(jìn)行處理瘟檩。
  • Camera 方向與 Activity 方向不一致,需要進(jìn)行多角度兼容澈蟆。
  • 進(jìn)行 YUV 轉(zhuǎn) RGB 和圖片旋轉(zhuǎn)墨辛,兩個(gè)步驟加起來(lái)比較耗時(shí)。

考慮到 YUV 轉(zhuǎn) RGB 是一個(gè)個(gè)像素點(diǎn)進(jìn)行轉(zhuǎn)換的趴俘。

而 RGB 圖片旋轉(zhuǎn)也是一個(gè)個(gè)像素點(diǎn)進(jìn)行變換的背蟆。

那么可以?xún)蓚€(gè)過(guò)程合并處理,根據(jù)旋轉(zhuǎn)角度的不同進(jìn)行不同方向的遍歷存儲(chǔ)哮幢。


Camera 默認(rèn)幀的 YUV 格式為 NV21 (YUV420SP带膀,不了解的可以看這篇文章 YUV 格式 )。

所以基于 NV21 轉(zhuǎn) RGB 同時(shí)實(shí)現(xiàn) RGB 圖片的旋轉(zhuǎn)橙垢。

處理 XY 坐標(biāo)變換的類(lèi)(寫(xiě)得復(fù)雜了些垛叨,可以按自己的想法寫(xiě))。


public class TwoDimensionalMatrixRotate {
    private int orienta;
    private int xmax;
    private int ymax;
    private int xmax_new;
    private int ymax_new;
    private int x_start;
    private int y_start;
    private int x_add;
    private int y_add;
    private int index;

    public TwoDimensionalMatrixRotate(int xmax, int ymax, int orienta) {
        init(xmax, ymax, orienta);
    }

    private void init(int _xmax, int _ymax, int _orienta) {
        orienta = _orienta;
        xmax = _xmax;
        ymax = _ymax;
        switch (orienta) {
            case   0:       // x + y * xmax
                xmax_new = xmax;
                ymax_new = ymax;

                x_start = 0;
                x_add   = +1;
                y_start = 0;
                y_add   = +xmax;

                index = calcIndex();   // 0;
                break;

            case  90:       // ymax - y - 1 + x * ymax
                xmax_new = ymax;
                ymax_new = xmax;

                x_start = 0;
                x_add   = +ymax;
                y_start = ymax - 1;
                y_add   = -1;

                index = calcIndex();   // ymax - 1;
                break;

            case 180:       // xmax - x - 1 + (ymax - y - 1) * xmax
                xmax_new = xmax;
                ymax_new = ymax;

                x_start = xmax - 1;
                x_add   = -1;
                y_start = ymax - 1;
                y_add   = -xmax;

                index = calcIndex();  // xmax * ymax - 1;
                break;

            case 270:       // y + (xmax - x - 1) * ymax
                xmax_new = ymax;
                ymax_new = xmax;

                x_start = xmax - 1;
                x_add   = -ymax;
                y_start = 0;
                y_add   = +1;

                index = calcIndex();   // (xmax - 1) * ymax;
                break;
        }
    }

    private int calcIndex() {
        int xx = x_start;
        int yy = y_start;
        int yy_add = Math.abs(y_add);

        if (orienta == 90 || orienta == 270) {
            xx = y_start;
            yy = x_start;
            yy_add = Math.abs(x_add);
        }

        return xx + yy * yy_add;
    }

    public int getXstart() {
        return x_start;
    }

    public int getXadd() {
        return x_add;
    }

    public int getYstart() {
        return y_start;
    }

    public int getYadd() {
        return y_add;
    }

    public int getIndex() {
        return index;
    }

    public int getPosition(int x, int y) {
        return (index + y * y_add + x * x_add);
    }
}

實(shí)現(xiàn) YUV 轉(zhuǎn) RGB 并旋轉(zhuǎn) RGB 圖片柜某。


private void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height, int orienta) {
    final int frameSize = width * height;

    int uvp, u, v;
    int y1192, y, r, g, b;

    TwoDimensionalMatrixRotate twoDimMatrixRotate = new TwoDimensionalMatrixRotate(width, height, orienta);

    final int x_add = twoDimMatrixRotate.getXadd();
    final int y_add = twoDimMatrixRotate.getYadd();
    final int index = twoDimMatrixRotate.getIndex();
    int flag = index;
    for (int j = 0, yp = 0; j < height; ++j, flag=index+j*y_add) {
        uvp = frameSize + (j >> 1) * width;
        u = v = 0;
        for (int i = 0; i < width; ++i, ++yp, flag+=x_add) {
            y = (0xff & ((int) yuv420sp[yp])) - 16;
            if (y < 0) {
                y = 0;
            }
            if ((i & 1) == 0) {
                v = (0xff & yuv420sp[uvp++]) - 128;
                u = (0xff & yuv420sp[uvp++]) - 128;
            }

            y1192 = 1192 * y;
            r = (y1192 + 1634 * v);
            g = (y1192 -  833 * v - 400 * u);
            b = (y1192 + 2066 * u);

            if (r < 0) { r = 0; } else if (r > 262143) { r = 262143; }
            if (g < 0) { g = 0; } else if (g > 262143) { g = 262143; }
            if (b < 0) { b = 0; } else if (b > 262143) { b = 262143; }

            rgb[flag] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
        }
    }
}

原理:

NV21 (YUV420SP)轉(zhuǎn) RGB 是一行一行的存儲(chǔ) RGB 像素點(diǎn)嗽元。

只需要更改存儲(chǔ)的順序,就可以實(shí)現(xiàn)同步的 RGB 旋轉(zhuǎn)喂击。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末剂癌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子翰绊,更是在濱河造成了極大的恐慌佩谷,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件监嗜,死亡現(xiàn)場(chǎng)離奇詭異谐檀,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)裁奇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)桐猬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人刽肠,你說(shuō)我怎么就攤上這事溃肪∶馕福” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵惫撰,是天一觀的道長(zhǎng)羔沙。 經(jīng)常有香客問(wèn)我,道長(zhǎng)润绎,這世上最難降的妖魔是什么撬碟? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮莉撇,結(jié)果婚禮上呢蛤,老公的妹妹穿的比我還像新娘。我一直安慰自己棍郎,他們只是感情好其障,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著涂佃,像睡著了一般励翼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辜荠,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天汽抚,我揣著相機(jī)與錄音,去河邊找鬼伯病。 笑死造烁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的午笛。 我是一名探鬼主播惭蟋,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼药磺!你這毒婦竟也來(lái)了告组?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤癌佩,失蹤者是張志新(化名)和其女友劉穎木缝,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體驼卖,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡氨肌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了酌畜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卿叽,死狀恐怖桥胞,靈堂內(nèi)的尸體忽然破棺而出恳守,到底是詐尸還是另有隱情,我是刑警寧澤贩虾,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布催烘,位于F島的核電站,受9級(jí)特大地震影響缎罢,放射性物質(zhì)發(fā)生泄漏伊群。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一策精、第九天 我趴在偏房一處隱蔽的房頂上張望舰始。 院中可真熱鬧,春花似錦咽袜、人聲如沸丸卷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)谜嫉。三九已至,卻和暖如春凹联,著一層夾襖步出監(jiān)牢的瞬間沐兰,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工蔽挠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留住闯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓象泵,卻偏偏與公主長(zhǎng)得像寞秃,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子偶惠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 由于H.264等壓縮算法都是在YUV的顏色空間上進(jìn)行的春寿,所有在進(jìn)行壓縮前,首先要進(jìn)行顏色空間的轉(zhuǎn)換忽孽。如果攝像頭采集...
    眷卿三世閱讀 13,580評(píng)論 2 6
  • 一绑改、文章說(shuō)明 上周開(kāi)始寫(xiě)直播相關(guān)的文章,寫(xiě)了一篇手機(jī)直播總覽的文章兄一,沒(méi)想到得到大家很多贊和關(guān)注厘线,在此感謝大家支持。...
    風(fēng)從影閱讀 19,840評(píng)論 33 133
  • JPEG( Joint Photographic Experts Group)是一種圖像壓縮標(biāo)準(zhǔn), 也是目前使用最...
    幽客閱讀 18,604評(píng)論 1 15
  • 文章參考: 圖文詳解YUV420數(shù)據(jù)格式 YUV主要采樣格式理解 YUV格式詳解 百度百科和維基百科 概述 本文基...
    Felix_lin閱讀 3,534評(píng)論 0 5
  • 從簡(jiǎn)書(shū) (平水韻) 汗青成簡(jiǎn)書(shū)心得出革,堅(jiān)守日更貪墨多造壮。 網(wǎng)海懸珠覓同道,錚規(guī)唱和共研磨。 從QQ達(dá)人到微信達(dá)人耳璧,再想...
    聞笛柳閱讀 340評(píng)論 4 6