在PreviewCall的表面背面,我们在相机预览中获得了YUV420SP格式,但是由于该图像的旋转错误,我想要正确旋转YUV图像,因为我需要通过网络发送它。因此需要应用正确的旋转。
我发现这个链接确实正确旋转但图像颜色松散。
还检查了Rotate an YUV byte array on Android,但没有正确显示图片。
我确实已经检查了stckoverflow上的链接,但没有一个人能够正确使用android环境中的代码。
任何人都知道如何正确旋转NV21图像字节[]并正确保留其颜色信息。
答案 0 :(得分:7)
如果您只想旋转NV21,以下代码将会有所帮助。 (我修改了代码from here)
public static void rotateNV21(byte[] input, byte[] output, int width, int height, int rotation) {
boolean swap = (rotation == 90 || rotation == 270);
boolean yflip = (rotation == 90 || rotation == 180);
boolean xflip = (rotation == 270 || rotation == 180);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int xo = x, yo = y;
int w = width, h = height;
int xi = xo, yi = yo;
if (swap) {
xi = w * yo / h;
yi = h * xo / w;
}
if (yflip) {
yi = h - yi - 1;
}
if (xflip) {
xi = w - xi - 1;
}
output[w * yo + xo] = input[w * yi + xi];
int fs = w * h;
int qs = (fs >> 2);
xi = (xi >> 1);
yi = (yi >> 1);
xo = (xo >> 1);
yo = (yo >> 1);
w = (w >> 1);
h = (h >> 1);
// adjust for interleave here
int ui = fs + (w * yi + xi) * 2;
int uo = fs + (w * yo + xo) * 2;
// and here
int vi = ui + 1;
int vo = uo + 1;
output[uo] = input[ui];
output[vo] = input[vi];
}
}
}
答案 1 :(得分:0)
Eddy Yong的代码只能在180度下很好地工作,但是在这里获得了一些好评,在其他SO主题和其他类似内容(例如github讨论)上也有很多粘贴,所以我决定适当地留在这里为未来的研究人员解答,以及旋转方法,该方法适用于90、180和270度。
public static byte[] rotateNV21(final byte[] yuv,
final int width,
final int height,
final int rotation)
{
if (rotation == 0) return yuv;
if (rotation % 90 != 0 || rotation < 0 || rotation > 270) {
throw new IllegalArgumentException("0 <= rotation < 360, rotation % 90 == 0");
}
final byte[] output = new byte[yuv.length];
final int frameSize = width * height;
final boolean swap = rotation % 180 != 0;
final boolean xflip = rotation % 270 != 0;
final boolean yflip = rotation >= 180;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
final int yIn = j * width + i;
final int uIn = frameSize + (j >> 1) * width + (i & ~1);
final int vIn = uIn + 1;
final int wOut = swap ? height : width;
final int hOut = swap ? width : height;
final int iSwapped = swap ? j : i;
final int jSwapped = swap ? i : j;
final int iOut = xflip ? wOut - iSwapped - 1 : iSwapped;
final int jOut = yflip ? hOut - jSwapped - 1 : jSwapped;
final int yOut = jOut * wOut + iOut;
final int uOut = frameSize + (jOut >> 1) * wOut + (iOut & ~1);
final int vOut = uOut + 1;
output[yOut] = (byte)(0xff & yuv[yIn]);
output[uOut] = (byte)(0xff & yuv[uIn]);
output[vOut] = (byte)(0xff & yuv[vIn]);
}
}
return output;
}