Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/215.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在android camera2中将yuv420转换为jpeg_Java_Android_Image Processing_Jpeg_Yuv - Fatal编程技术网

Java 在android camera2中将yuv420转换为jpeg

Java 在android camera2中将yuv420转换为jpeg,java,android,image-processing,jpeg,yuv,Java,Android,Image Processing,Jpeg,Yuv,我正在尝试将android camera2中获得的yuv 420预览帧保存为jpeg格式。我找到的唯一方法是将yuv420转换为nv21,构造一个yuvimage,然后使用compresstojpeg方法获得jpeg。为了从yuv420转换为jpeg,我使用下面的逻辑 Image.Plane Y = img.getPlanes()[0]; Image.Plane U = img.getPlanes()[2]; Image.P

我正在尝试将android camera2中获得的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数据是所需UV数据的两倍,但第一个副本恰好是正确的布局…,并且如果宽度==行跨距。宽度==行跨距是否取决于分辨率;由于硬件限制,通常步幅必须是16像素的倍数或类似的值。例如,对于不是16的倍数的分辨率,您的代码将无法工作

请解决这两个问题-注意行和像素步幅;否则,您可能会意外地使其在设备上工作,并且仍然会在具有不同步幅参数的设备上损坏它

编辑:

一些可以进行这种转换的C++代码可以在Android AOSP相机服务代码中找到:p> 供参考的映射:

预览HAL_像素_格式_YCrCb_420_SP的格式为NV21。 src.data是平面0 src.dataCb是平面1 src.dataCr是平面2 src.stride是平面0 rowStride src.chromaStride为平面1和2 src.chromaStep是平面1和2像素 平面0像素步长为1
谢谢你的意见。你有任何参考资料我可以查找这个转换的算法吗?我没有java参考手册,但是增加了C++代码参考书!这是完美的。我只需要切换Cr和Cb的定义就可以正确显示颜色。