Bitmap和libyuv在JNI中的字节序
文章目录
- 1. 问题
- 2. libyuv
- 2.1 FOURCC (Four Charactacter Code)
- 2.2 libyuv中FOURCC
- 3. Bitmap
- 4. libyuv 转换
1. 问题
Android
中在使用RGB数据的时候我们会遇到color space
的stored in computer memory的问题。
通常有两种典型的scheme来记录RGB数据:
- byte order——按照字节顺序
- word order——按照字面顺序
- 大端字节序的环境 big-endian system
byte order
和Word order
的顺序是一致的
- 小端字节序 little-endian system
byte order
和word order
是相反的,比如ARGB(word-order)
的内存字节序存储为BGRA(byte order)
所以,我们在Android中使用RGB数据的时候是使用哪种scheme(word order | byte order
)标记的format(RGB
)一定要清楚。
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++
语言,是小端字节序。所以word order和byte order是相反的。看libyuv
的源码也能看得出来。
在源码row_common.cc
文件中
MAKEROWY(ARGB, 2, 1, 0, 4) //ARGB(word order)-->BGRA(byte order)-->2,1,0-->RGBMAKEROWY(BGRA, 1, 2, 3, 4) //BGRA(word order)-->ARGB(byte order)-->1,2,3-->RGBMAKEROWY(ABGR, 0, 1, 2, 4)//ABGR(word order)-->RGBA(byte order)-->0,1,2-->RGBMAKEROWY(RGBA, 3, 2, 1, 4)MAKEROWY(RGB24, 2, 1, 0, 3)
MAKEROWY(ARGB, 2, 1, 0, 4)
中ARGB
是使用的word order
,所以它的byte order
是BGRA
,后面的2,1,0
,是字节序中的索引,每个取出来后刚好是RGB
3. Bitmap
当我们在JNI中使用Bitmap
时,需要取出pixel数据的时候同样涉及到实际的内存字节序问题,只有正确知道了字节序也就是byte order
,我们才能正确的转换。
-
NDK中的
ANDROID_BITMAP_FORMAT_RGBA_8888
,c/c++
语言默认小端字节序- 这里的
ANDROID_BITMAP_FORMAT_RGBA_8888
的byte order
为ABGR
- 这里的
-
应用层
Bitmap.Config.ARGB_8888
,java
语言默认大端字节序,word order
和byte order
是一样的,但是doc上给出的实际字节序的打包方式为ABGR
://字节序为 ABGRint color = (A & 0xff) << 24 | (B & 0xff) << 16 | (G & 0xff) << 8 | (R & 0xff);
-
Android平台OpenGL ES 的glReadPixels的读取type为
GL_RGBA
时,实际byte order
也为ABGR
4. libyuv 转换
I420
是YUV420格式转换的基准类型,任何要转换为YUV420的数据都可以通过先转换为I420
再转换得到ARGB
是RGB格式转换的基准类型
RGBA color space
更多相关文章
- 一句话锁定MySQL数据占用元凶
- Android短信数据库字段描述
- [置顶] Android(安卓)Camera系统
- Android(安卓)sqlite 操作
- SharedPreference用法
- android中webservce获取soapObject数据的解析问题
- SQLite_Android
- [Android]使用AdapterTypeRender对不同类型的item数据到UI的渲染
- android 数据库操作 插入彩信,数据库子查询