1.前言
在之前的文章中分析了YUV转RGB的相关内容,这在跟硬件层的数据处理时比较方便,yuv数据均存在一个数组中,但是在研究arcore unity层代码时通过CameraImageBytes的类型传给应用层。ARCORE通过YUV三层将各层的数据传到上层,所以处理时相对来说更简单。
2.代码
转换代码:
public static byte[] CameraImageToRGB(CameraImageBytes imageBytes)
{
int w = imageBytes.Width;
int h = imageBytes.Height;
byte[] Y = new byte[w * h];
byte[] UV = new byte[w * h / 2];
byte[] RGB = new byte[w * h * 3];
//byte[] RGBA = new byte[w * h * 4];
Marshal.Copy(imageBytes.Y, Y, 0, w * h);
Marshal.Copy(imageBytes.U, UV, 0, w * h / 2);
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
int y = Y[w * i + j] & 0xFF;
int u = UV[((i / 2) * (w / 2) + j / 2) * 2 + 0] & 0xFF;
int v = UV[((i / 2) * (w / 2) + j / 2) * 2 + 1] & 0xFF;
int r = (256 * y + 351 * (v - 128)) >> 8;
int g = (256 * y - 086 * (u - 128) - 179 * (v - 128)) >> 8;
int b = (256 * y + 444 * (u - 128)) >> 8;
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
RGB[(i * w + j) * 4 + 0] =(byte)(r & 0xFF);
RGB[(i * w + j) * 4 + 1] =(byte)(g & 0xFF);
RGB[(i * w + j) * 4 + 2] =(byte)(b & 0xFF);
//RGB[(i * w + j) * 4 + 3] =1;
}
}
return RGB;
}
如果将CameraImageBytes转化为nv21,则:
public static byte[] CameraImageToNV21(CameraImageBytes imageBytes)
{
int w = imageBytes.Width;
int h = imageBytes.Height;
byte[] nv21 = new byte[(int)(w * h * 1.5f)];
byte[] uv = new byte[w * h / 2];
Marshal.Copy(imageBytes.Y, nv21, 0, w * h);
Marshal.Copy(imageBytes.U, uv, 0, w * h / 2);
for (int i = 0; i < w*h/4; i++)
{
nv21[w * h + 2 * i + 0] = uv[2 * i + 1];
nv21[w * h + 2 * i + 1] = uv[2 * i + 0];
}
return nv21;
}
3.结论
。。。