Android 关于 YUV NV21 转换为 RGB 的困惑
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12469730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Confusion on YUV NV21 conversion to RGB
提问by Cheok Yan Cheng
According to http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21, NV21 is the default used format.
根据http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21,NV21 是默认使用的格式。
There are quite a number of code on web regarding YUV NV21 to RGB conversion. However, when I go through the code, I doubt on the correctness of the code.
网上有很多关于 YUV NV21 到 RGB 转换的代码。但是,当我浏览代码时,我怀疑代码的正确性。
The first component V should come first, followed by first component U
第一个组件 V 应该先出现,然后是第一个组件 U
According to http://wiki.videolan.org/YUV#NV21, NV21 is like NV12, but with U and V order reversed: it starts with V.
However, when I went through the code implementation
根据http://wiki.videolan.org/YUV#NV21,NV21 is like NV12, but with U and V order reversed: it starts with V.
但是,当我完成代码实现时
- http://pastebin.com/T0my7zSc- It assumes U comes first
- https://stackoverflow.com/a/8394202/72437- It assumes U comes first too
- https://stackoverflow.com/a/10125048/72437- It assmes U comes first too
- http://pastebin.com/T0my7zSc- 假设你是第一位的
- https://stackoverflow.com/a/8394202/72437- 假设 U 也是第一位的
- https://stackoverflow.com/a/10125048/72437- 它也让你先入为主
R should be the most significant positionAccording implementation of int argb
in Color.java, R suppose to be at the most significant position. However, I went through the following code implementation
[R应该是最显著位置的根据实施int argb
在Color.java,R假设是在最显著位置。但是,我经历了以下代码实现
- http://pastebin.com/T0my7zSc- It assumes R is in least significant position
- https://stackoverflow.com/a/8394202/72437- It assumes R is in least significant position
- http://pastebin.com/T0my7zSc- 它假设 R 处于最不重要的位置
- https://stackoverflow.com/a/8394202/72437- 它假设 R 处于最不重要的位置
I was wondering, are they making common mistake, or I have overlooked something?
我想知道,他们是否犯了常见的错误,或者我忽略了什么?
Currently, my implementation is as follow.
目前,我的实现如下。
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;
}
}
}
采纳答案by Victor Ronin
First of all, I am not super experienced with image encoding (has some limited exposure to this about a year ago). So, take my answer with grain of salt.
首先,我对图像编码的经验并不丰富(大约一年前对此有一些有限的接触)。所以,请接受我的回答。
However, I believe you are right. I think in their code both a) V and U are flipped b) R and B are flipped
不过,我相信你是对的。我认为在他们的代码中 a) V 和 U 被翻转 b) R 和 B 被翻转
I have a feeling that when both of these things are flipped, it will produce the same result as if they arent' flipped. That's the reason why you can find wrong code in many places (originally, somebody got it wrong and after it was copied all over the places, because the resulting code works (however, variables named incorrectly)).
我有一种感觉,当这两个东西都被翻转时,它会产生与它们没有翻转一样的结果。这就是为什么您可以在许多地方找到错误代码的原因(最初,有人弄错了,然后将其复制到各处,因为结果代码有效(但是,变量命名不正确))。
Here is another example of code (which works the same as yours): http://www.41post.com/3470/programming/android-retrieving-the-camera-preview-as-a-pixel-array
这是另一个代码示例(与您的相同):http: //www.41post.com/3470/programming/android-retrieving-the-camera-preview-as-a-pixel-array
回答by Reality Pixels
Terms like "most significant position" are ambiguous, because it depends on the endian of the machine.
像“最重要的位置”这样的术语是不明确的,因为它取决于机器的字节序。
When all data types are 8 bits, there is an easy unambiguous specification: byte order. For example, unsigned char rgba[4]; would have the data stored as rgba[0] = r; rgba[1] = g; rgba[2] = b; rgba[3] = a;
当所有数据类型都是 8 位时,有一个简单明确的规范:字节顺序。例如,unsigned char rgba[4]; 将数据存储为 rgba[0] = r; rgba[1] = g; rgba[2] = b; rgba[3] = 一个;
or {r, g, b, a } regardless of the endianness of the processor.
或 {r, g, b, a } 无论处理器的字节序如何。
If instead you did
如果你做了
int32 color = (r << 24) | (g << 16) | (b << 8) | (a << 0);
int32 颜色 = (r << 24) | (g << 16) | (b << 8) | (a << 0);
you would get { r, g, b, a } on a big-endian system, and { a, r, g, b } on a little-endian system. Do you work on systems that have heterogeneous processors? Like maybe you have a CPU and a GPU? How do they know which endian the other is using? You are much better off defining the byte ordering.
你会在大端系统上得到 { r, g, b, a } ,在小端系统上得到 { a, r, g, b } 。您是否在具有异构处理器的系统上工作?也许你有一个 CPU 和一个 GPU?他们怎么知道对方使用的是哪个字节序?你最好定义字节顺序。