gpt4 book ai didi

java - 在androidcamera2中将yuv420转换为jpeg

转载 作者:行者123 更新时间:2023-12-02 13:42:34 26 4
gpt4 key购买 nike

我正在尝试将 androidcamera2 中获得的 yuv 420 预览帧保存为 jpeg。我发现这样做的唯一方法是将 yuv420 转换为 nv21,构建 yuvimage,然后使用 compresstojpeg 方法获取 jpeg。为了从 yuv420 转换为 jpeg,我使用下面的逻辑

            Image.Plane Y = img.getPlanes()[0];
Image.Plane U = img.getPlanes()[2];
Image.Plane V = img.getPlanes()[1];

int Yb = Y.getBuffer().remaining();
int Ub = U.getBuffer().remaining();
int Vb = V.getBuffer().remaining();

byte[] data = new byte[Yb + Ub + Vb];

Y.getBuffer().get(data, 0, Yb);
U.getBuffer().get(data, Yb, Ub);
V.getBuffer().get(data, Yb + Ub, Vb);

YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21,
mPreviewSize.getWidth(), mPreviewSize.getHeight(), null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(0, 0,
mPreviewSize.getWidth(), mPreviewSize.getHeight()),
100, out);

但是,这会导致某些分辨率 144 x 176、176x144、352x288、480x360、1280x960 获得绿色图像。转换为nv21的逻辑是否正确?我还可以使用什么其他方法将 yuv420 转换为 jpeg。有没有相关的 Java/Android api?

最佳答案

不,这是不正确的 - 您没有注意平面的行跨距或像素跨距。

您必须解析这些内容,并确保您的输出缓冲区实际上与 YuvImage 的 NV21 输入的输入期望相匹配,该输入假设行步长 = 宽度和交错的 V/U 平面。

只有当输入图像 U/V 平面实际上交错时,您拥有的代码才会起作用(在这种情况下,您将添加所需 UV 数据的两倍,但第一个副本恰好是正确的布局...),如果宽度==行步幅。 width==row stride 是否取决于分辨率;由于硬件限制,通常步幅必须是 16 像素的倍数或类似的值。例如,对于不是 16 倍数的分辨率,您的代码将无法工作。

请解决这两个问题 - 注意行和像素步幅;否则,您可能会意外地使其在您的设备上正常工作,但在具有不同步幅参数的设备上仍然会出现故障。

编辑:

可以在 Android AOSP 相机服务代码中找到一些执行此类转换的示例 C++ 代码: CallbackProcessor::convertFromFlexibleYuv

引用映射:

  • HAL_PIXEL_FORMAT_YCrCb_420_SP 的预览格式为 NV21。
  • src.data 为平面 0
  • src.dataCb 是平面 1
  • src.dataCr 是平面 2
  • src.stride 是平面 0 rowStride
  • src.chromaStride 是平面 1 和 2 rowStride
  • src.chromaStep 是平面 1 和 2 PixelStride
  • 平面 0 像素步长为 1

关于java - 在androidcamera2中将yuv420转换为jpeg,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42659824/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com