Android Camera2 YUV_420_888格式转换为YUV422(YUYV)

已经有很多文章介绍Image对象,这里不再多解释.

写在这里一是为了做个笔记记录,二是查了好多资料确实没有找到YUV_420_888转换YUYV的方法,希望帮助更多人吧.

public static byte[] getYUYVFromImage420(Image image) {
    try {
        //获取源数据,如果是YUV格式的数据planes.length = 3
        //plane[i]里面的实际数据可能存在byte[].length <= capacity (缓冲区总大小)
        final Image.Plane[] planes = image.getPlanes();

        //数据有效宽度,一般的,图片width <= rowStride,这也是导致byte[].length <= capacity的原因
        //所以我们只取width部分
        int width = image.getWidth();
        int height = image.getHeight();
        //此处用来装填最终的YUV数据,需要2倍的图片大小,因为Y U V 比例为 4:2:2
        byte[] yuvBytes = new byte[width * height * ImageFormat.getBitsPerPixel(ImageFormat.YUV_422_888) / 8];

        //临时存储y u v数据的
        byte[] yBytes = new byte[width * height];

        //--分离Y数据
        ByteBuffer buffer = planes[0].getBuffer();
        buffer.get(yBytes);


        int uPixelsStride, vPixelsStride;
        //--分离U数据
        uPixelsStride = planes[1].getPixelStride();
        buffer = planes[1].getBuffer();
        byte[] uTempBytes = new byte[buffer.capacity()];
        buffer.get(uTempBytes);

        vPixelsStride = planes[2].getPixelStride();
        //--分离V数据
        buffer = planes[2].getBuffer();
        byte[] vTempBytes = new byte[buffer.capacity()];
        buffer.get(vTempBytes);

        int ySrcIndex = 0;
        int uSrcIndex = 0;
        int vSrcIndex = 0;

        int yDstIndex = 0;

        for (int j = 0; j < height / 2; j++) {
            int uvWidth = width;
            for (int k = 0; k < uvWidth / 2; k++) {
                // Y
                yuvBytes[yDstIndex] = yBytes[ySrcIndex];
                yuvBytes[yDstIndex + uvWidth * 2] = yBytes[ySrcIndex + uvWidth];
                yDstIndex++;
                ySrcIndex++;

                // U
                yuvBytes[yDstIndex] = uTempBytes[uSrcIndex];
                yuvBytes[yDstIndex + uvWidth * 2] = uTempBytes[uSrcIndex];
                yDstIndex++;

                // Y
                yuvBytes[yDstIndex] = yBytes[ySrcIndex];
                yuvBytes[yDstIndex + uvWidth * 2] = yBytes[ySrcIndex + uvWidth];
                yDstIndex++;
                ySrcIndex++;

                // V
                yuvBytes[yDstIndex] = vTempBytes[vSrcIndex];
                yuvBytes[yDstIndex + uvWidth * 2] = vTempBytes[vSrcIndex];
                yDstIndex++;

                uSrcIndex += uPixelsStride;
                vSrcIndex += vPixelsStride;
            }
            yDstIndex += uvWidth * 2;
            ySrcIndex += uvWidth;
        }

        image.close();
        return yuvBytes;
    } catch (final Exception e) {
        if (image != null) {
            image.close();
        }
        Log.e("ArMn", android.util.Log.getStackTraceString(e));
    }
    return null;
}

你可能感兴趣的:(Android Camera2 YUV_420_888格式转换为YUV422(YUYV))