http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21によると、NV21がデフォルトで使用される形式です。
YUV NV21からRGBへの変換に関しては、Web上にかなりの数のコードがあります。しかし、私がコードを調べているとき、私はコードの正確さに疑問を持っています。
最初のコンポーネントVが最初に来て、次に最初のコンポーネントUが来るはずです
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-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;
}
}
}