【问题标题】:android camera2 get nv21 byte array from preview imageandroid camera2从预览图像中获取nv21字节数组
【发布时间】:2019-03-22 03:22:48
【问题描述】:

我正在尝试从 camera2 API 的预览帧中获取黑白值(Y 平面)。这是我目前所拥有的:

public void onImageAvailable(ImageReader, reader) {
   Image image = reader.acquireLatestImage();
   Image.Plane[] planes = image.getPlanes();
   ByteBuffer yPlane = planes[0].getBuffer();
   if (firstRun) {
      ySize = yPlane.remaining();
      nv21 = new byte[ySize];
   }
   yPlane.get(nv21, 0, ySize);
   Log.i(TAG, String.valueOf(nv21.length) + " " + String.valueOf(nv21[0]));
   image.close();
}

但是,数组的长度并不像预期的那样(1280*960=1 228 800,nv21.length 返回 12 979 200)并且 nv21[0] 给出了随机值。 我做错了什么?

提前谢谢你

【问题讨论】:

  • 请提供您如何创建 ImageReader 的代码。是YUV_420_888格式吗?
  • imageReader = ImageReader.newInstance(size.getWidth(), size.getHeight(), ImageFormat.YUV_420_888, 3); imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler);

标签: android android-camera2


【解决方案1】:

缓冲区的大小不必正好是 1280*960,因为每行像素之间可以有row stride。也就是说,总大小的 10 倍差异似乎令人惊讶,但并非不可行 - 检查值是多少。

我建议尝试将 Y 平面实际绘制到 ImageView 中(为了调试,这并不需要高效,因此您可以只使用 Bitmap 和 Canvas 和 drawColor),看看它的样子。它只是完整的垃圾,还是带有奇怪填充的真正 Y 平面等?

【讨论】:

  • 在我的情况下,rowStride 等于 4160,但我不确定我是否完全理解行/行跨步的概念。这是否意味着我的图像的第一行在元素 0-959 中表示,第二行从元素 960+4160 到元素 1919+4160?因为在这种情况下,我的 Y 数组的总长度仍然太长:12 979 200 - (1280*4160) = 7 654 400 而不是 1 228 800 (= 1280*960)。
  • 不,行 Y 开始于位置 rowStrideY 并结束于位置 rowStrideY+width-1,因此整个缓冲区大小将是 (rowStride * (height - 1) + width) = 4160 * 959 + 1280 = 3990720,这仍然远小于您看到的缓冲区大小。 (最后一行不包括行填充,因为没有理由包括它)我仍然会检查前 4 MB 的数据是否是有效的 Y 平面,而忽略其余的,但它通常不应该是这样做。您也可以尝试使用 BitmapFactory 对其进行解码,以查看它是否是 JPEG。
猜你喜欢
  • 2017-09-09
  • 1970-01-01
  • 2018-05-31
  • 1970-01-01
  • 1970-01-01
  • 2017-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多