更新:我联系了设备供应商,他们告诉我它使用的是平面 4:2:0 YUV 全尺寸像素格式。经过研究,我发现 YUV 4:2:0 似乎有 3 种主要格式:I420、J420 和 YV12。 我很兴奋,因为在 android YuvImage 类中有这种图像格式的常量,但是在运行我的代码时我得到了以下异常:
java.lang.IllegalArgumentException: only support ImageFormat.NV21 and ImageFormat.YUY2 for now
那真是太可惜了..
我尝试编写一些简单的函数来交错 2 个色度平面,如 NV21 像素格式图像中所示。
public static void convertYUY420ToNV21(byte[] data_yuv420, byte[] data_yuv_N21) {
int idx = (int) (data_yuv_N21.length * (2.0f / 3.0f));
int j = idx;
int chroma_plane_end = (int) (idx + ((data_yuv_N21.length - idx) / 2));
for (int i = idx; i < chroma_plane_end; i++) {
data_yuv_N21[j] = data_yuv420[i];
j += 2;
}
j = idx + 1;
for (int i = chroma_plane_end; i < data_yuv_N21.length; i++) {
data_yuv_N21[j] = data_yuv420[i];
j += 2;
}
但是,结果似乎仍然与我的原始代码相同。 我考虑的一个可能原因是字节数组的大小 (1843200)。我读到对于 YUV420,一个像素的深度是 12 位。相机分辨率为 1280x720,即 921,600 像素或 1,382,400 字节。这比实际字节数组大小小三分之一。我读到飞机之间可能有一些填充物,但我仍然不知道如何找到它。
YuvImage 类在其构造函数中有一个 strides 参数,但即使在阅读了 android 开发人员文档后我也不确定如何使用。
有什么线索吗?
原帖:
我遇到以下问题:我正在尝试访问设备的摄像头,但没有提供有关所用摄像头类型或图像格式的信息。提供的唯一信息是关于如何检索包含视频流输出的字节数组。 然而,我发现分辨率是 1280x720,字节数组大小是 1843200。通过谷歌搜索,我偶然发现了使用 YUYV 和类似像素格式的大小和尺寸完全相同的相机。 基于这些知识,我编写了以下代码:
ByteArrayOutputStream out = new ByteArrayOutputStream();
YuvImage yuv = new YuvImage(data, ImageFormat.YUY2, 1280, 720, null);
yuv.compressToJpeg(new Rect(0, 0, 1280, 720), 100, out);
byte[] bytes = out.toByteArray();
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
if (bitmap != null) {
ImageView cameraImageView = (ImageView) findViewById(R.id.imageView);
cameraImageView.setImageBitmap(bitmap);
}
BitmapFactory.decodeByteArray 函数返回了一个有效的位图,但在显示它时我看到图像有绿色和紫色 Blob ,可能与颜色 channel 有关? 样本图片:
有没有办法找出已使用的确切像素格式/编码?我不确定从现在开始还有什么其他的尝试。 感谢任何建议,谢谢!
最佳答案
试试这个:
/**
* Save YUV image data (NV21 or YUV420sp) as JPEG to a FileOutputStream.
*/
public static boolean saveYUYToJPEG(byte[] imageData,File saveTo,int format,int quality,int width,int height,int rotation,boolean flipHorizontally){
FileOutputStream fileOutputStream=null;
YuvImage yuvImg=null;
try {
fileOutputStream=new FileOutputStream(saveTo);
yuvImg=new YuvImage(imageData,format,width,height,null);
ByteArrayOutputStream jpegOutput=new ByteArrayOutputStream(imageData.length);
yuvImg.compressToJpeg(new Rect(0,0,width - 1,height - 1),90,jpegOutput);
Bitmap yuvBitmap=BitmapFactory.decodeByteArray(jpegOutput.toByteArray(),0,jpegOutput.size());
Matrix imageMatrix=new Matrix();
if (rotation != 0) {
imageMatrix.postRotate(rotation);
}
if (flipHorizontally) {
}
yuvBitmap=Bitmap.createBitmap(yuvBitmap,0,0,yuvBitmap.getWidth(),yuvBitmap.getHeight(),imageMatrix,true);
yuvBitmap.compress(CompressFormat.JPEG,quality,fileOutputStream);
}
catch ( FileNotFoundException e) {
return false;
}
return true;
}
关于java - 使用平面 4 :2:0 YUV full scale pixel format 将图像从字节数组转换为位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47586625/