近期在弄Android外置usb摄像头开发,所获取到的数据是RGB565的,但是接收方必须要是YUV420SP格式的。(接口是基于Android手机摄像头的数据格式NV21来写的,现在要用usb摄像头所以导致数据不通)
之前接触到的都是底层C来转,现在要自己动手了。百度基本都是YUV转RGB的,偶尔有RGB转YUV的也是C语言的。
也翻到一篇关于java的,但是是图片转YUV,传入类型是通过bitmap来获取到的int[],而我获取到的数据源是byte[]的RGB565格式,用byte[]转成int[],不能用。
试着翻译C,很多基本数据不会翻译。没走通。。。
又看起之前找到的一篇java代码:Java实现的RGB转YUV420方法
接下来寻找怎样把我的byte[]转换成int[],无意中,真的是无意中发现的。RGB565 数据 如何 保存为图片
终于找到了我想要的
下面进入拼接环节了,先将byte[]转成int[],然后转YUV,居然成功跑起来了。
但是画面数据怎么是这个样子
能确定转是转成功了,但是有瑕疵。
最后实在不知道哪里的问题,请教了大佬。问我这个byte有没有符号。一脸懵逼,后来查了下,把byte转成int的符号去掉。运行,完美!
下面是代码,特此记录:以后基础还需多多努力
public static byte[] rgb565toYuv420sp(byte[] rgb565, int width, int height) {
int len = width * height;
byte[] yuv = new byte[len * 3 / 2];
int y, u, v;
int tmpColor[] = new int[width * height];
for (int j = 0; j < width * height; j++) {
// 去掉字节符号,图像字节都是无符号的
int c = rgb565[j * 2 + 0] & 0x0ff;
int d = rgb565[j * 2 + 1] & 0x0ff;
int tmpint = c + d * 256;
int a = 0xff;
int r = (tmpint & 0xf800) >> 11;
int g = (tmpint & 0x07e0) >> 5;
int b = (tmpint & 0x001f);
r = r << 3;
g = g << 2;
b = b << 3;
tmpColor[j] = (a << 24) | (r << 16) | (g << 8) | (b);
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// 屏蔽ARGB的透明度值
int rgb = tmpColor[i * width + j] & 0x00FFFFFF;
// 像素的颜色顺序为bgr,移位运算。
int r = rgb & 0xFF;
int g = (rgb >> 8) & 0xFF;
int b = (rgb >> 16) & 0xFF;
// 套用公式
y = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
// 调整
y = y < 16 ? 16 : (y > 255 ? 255 : y);
u = u < 0 ? 0 : (u > 255 ? 255 : u);
v = v < 0 ? 0 : (v > 255 ? 255 : v);
// 赋值
yuv[i * width + j] = (byte) y;
yuv[len + (i >> 1) * width + (j & ~1) + 0] = (byte) u;
yuv[len + +(i >> 1) * width + (j & ~1) + 1] = (byte) v;
}
}
return yuv;
}