Bitmap和libyuv在JNI中的字節(jié)序

1. 問題

Android中在使用RGB數(shù)據(jù)的時候我們會遇到color space 的stored in computer memory的問題。
通常有兩種典型的格式來記錄RGB數(shù)據(jù):

  1. byte order——按照字節(jié)順序
  2. word order——按照字面順序
  • 大端字節(jié)序的環(huán)境 big-endian system
    • byte orderWord order的順序是一致的
  • 小端字節(jié)序 little-endian system
    • byte orderword order 是相反的,比如 ARGB(word-order)的內(nèi)存字節(jié)序存儲為BGRA(byte order)

所以,我們在Android中使用RGB數(shù)據(jù)的時候是使用哪種scheme(word order | byte order)標記的format一定要清楚。

2. libyuv

2.1 FOURCC (Four Charactacter Code)

在下載的libyuv源碼里libyuv-refs-heads-master\docs\formats.md里有講述libyuv支持的FOURCC(這里):

On little endian machines, as an int, this would have 'A' in the lowest byte. The FOURCC macro reverses the order:

#define FOURCC(a, b, c, d) (((uint32)(a)) | ((uint32)(b) << 8) | ((uint32)(c) << 16) | ((uint32)(d) << 24))

So the "ARGB" string, read as an uint32, is

FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B')

If you were to read ARGB pixels as uint32's, the alpha would be in the high byte, and the blue in the lowest byte. In memory, these are stored little endian, so 'B' is first, then 'G', 'R' and 'A' last.

2.2 libyuv中FOURCC

libyuv使用C/C++語言,是小端字節(jié)序。所以word orderbyte order是相反的???code>libyuv的源碼也能看得出來。
在源碼row_common.cc文件中

MAKEROWY(ARGB, 2, 1, 0, 4)  //ARGB(word order)-->BGRA(byte order)-->2,1,0-->RGB
MAKEROWY(BGRA, 1, 2, 3, 4)  //BGRA(word order)-->ARGB(byte order)-->1,2,3-->RGB
MAKEROWY(ABGR, 0, 1, 2, 4)  //ABGR(word order)-->RGBA(byte order)-->0,1,2-->RGB
MAKEROWY(RGBA, 3, 2, 1, 4)
MAKEROWY(RGB24, 2, 1, 0, 3)

MAKEROWY(ARGB, 2, 1, 0, 4)ARGB是使用的word order,所以它的byte orderBGRA,后面的2,1,0,是字節(jié)序中的索引,每個取出來后剛好是RGB。

convert.h中的注釋

3. Bitmap

當我們在JNI中使用Bitmap時,需要取出pixel數(shù)據(jù)的時候同樣涉及到實際的內(nèi)存字節(jié)序問題,只有正確知道了字節(jié)序也就是byte order,我們才能正確的轉(zhuǎn)換。

  • NDK中的ANDROID_BITMAP_FORMAT_RGBA_8888c/c++語言默認小端字節(jié)序

    • 這里的ANDROID_BITMAP_FORMAT_RGBA_8888byte orderABGR
  • 應用層Bitmap.Config.ARGB_8888,java語言默認大端字節(jié)序,word orderbyte order是一樣的,但是doc上給出的實際字節(jié)序的打包方式為ABGR:

//字節(jié)序為  ABGR
int color = (A & 0xff) << 24 | (B & 0xff) << 16 | (G & 0xff) << 8 | (R & 0xff);
  • Android平臺OpenGL ES 的glReadPixels的讀取type為GL_RGBA時,實際byte order也為ABGR

4. libyuv 轉(zhuǎn)換

  • I420是YUV420格式轉(zhuǎn)換的基準類型,任何要轉(zhuǎn)換為YUV420的數(shù)據(jù)都可以通過先轉(zhuǎn)換為I420再轉(zhuǎn)換得到
  • ARGB是RGB格式轉(zhuǎn)換的基準類型

RGBA color space

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

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

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