YUV NV21转换成RGB的混淆

根据http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21,NV21是默认使用的格式。

网上有很多关于YUV NV21到RGB转换的代码。 但是,当我浏览代码时,我怀疑代码的正确性。

第一个分量V应该先来,然后是第一个分量U.

根据http://wiki.videolan.org/YUV#NV21,NV21 NV21 is like NV12, but with U and V order reversed: it starts with V.然而,当我通过代码实现

  • http://pastebin.com/T0my7zSc – 假设U先来
  • https://stackoverflow.com/a/8394202/72437 – 它假设U也是第一个
  • https://stackoverflow.com/a/10125048/72437 – 它尴尬U先来

R应该是最重要的位置根据Color.java中的int argb的实现 ,R应该处于最重要的位置。 不过,我经历了下面的代码实现

  • http://pastebin.com/T0my7zSc – 它假定R是最不重要的位置
  • https://stackoverflow.com/a/8394202/72437 – 它假定R是最不重要的位置

我想知道,他们是犯了一个常见的错误,还是我忽略了一些东西?

目前,我的实施如下。

 public static void YUV_NV21_TO_RGB(int[] argb, byte[] yuv, int width, int height) { final int frameSize = width * height; final int ii = 0; final int ij = 0; final int di = +1; final int dj = +1; int a = 0; for (int i = 0, ci = ii; i < height; ++i, ci += di) { for (int j = 0, cj = ij; j < width; ++j, cj += dj) { int y = (0xff & ((int) yuv[ci * width + cj])); int v = (0xff & ((int) yuv[frameSize + (ci >> 1) * width + (cj & ~1) + 0])); int u = (0xff & ((int) yuv[frameSize + (ci >> 1) * width + (cj & ~1) + 1])); y = y < 16 ? 16 : y; int r = (int) (1.164f * (y - 16) + 1.596f * (v - 128)); int g = (int) (1.164f * (y - 16) - 0.813f * (v - 128) - 0.391f * (u - 128)); int b = (int) (1.164f * (y - 16) + 2.018f * (u - 128)); r = r < 0 ? 0 : (r > 255 ? 255 : r); g = g < 0 ? 0 : (g > 255 ? 255 : g); b = b < 0 ? 0 : (b > 255 ? 255 : b); argb[a++] = 0xff000000 | (r << 16) | (g << 8) | b; } } } 

首先,我对图像编码不是很有经验(一年前有一些有限的曝光)。 所以,请用我的答案与盐。

不过,我相信你是对的。 我认为在他们的代码中a)V和U翻转b)R和B翻转

我有一种感觉,当这些事情都翻转了,它会产生相同的结果,如果他们不翻转。 这就是为什么你可以在很多地方find错误的代码的原因(原来,有人把它错误地复制到了所有的地方,因为结果代码工作(但是,variables命名不正确))。

下面是代码的另一个例子(它和你的一样): http : //www.41post.com/3470/programming/android-retrieving-the-camera-preview-as-a-pixel-array

像“最重要的位置”这样的术语是不明确的,因为它取决于机器的末端。

当所有的数据types都是8位时,有一个简单明了的规范:字节顺序。 例如,unsigned char rgba [4]; 将数据存储为rgba [0] = r; rgba [1] = g; rgba [2] = b; rgba [3] = a;

或{r,g,b,a},而不pipe处理器的字节顺序如何。

如果你做了

int32 color =(r << 24)| (g << 16)| (b << 8)| (a << 0);

你会得到{r,g,b,a}在一个大端系统上,{a,r,g,b}在一个小端系统上。 你是否在具有异构处理器的系统上工作? 也许你有一个CPU和一个GPU? 他们怎么知道对方正在使用哪一个endian? 你定义字节顺序要好得多。