i420转Yuyv

YUV的存储格式有两大类:packed和planar,还有SemiPlanar。

对于packed的YUV格式,每个像素点的Y,U,V是连续交错存储的。

对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。

i420转YuyvPacked

 public static byte[] i420ToYuyv(byte[] i420, int width, int height) {
        if (i420 == null || i420.length == 0 || i420.length != width * height * 3 / 2) {
            throw new IllegalArgumentException("invalid image params!");
        }
        byte[] yuyv = new byte[width * height * 2];
        int yuyvLineSize = width * 2;
        int i420YIndex = 0;
        int i420UIndex = width * height;
        int i420VIndex = width * height * 5 / 4;
        int yuyvLineStart = 0;
        for (int i = 0; i < height; i += 2) {
            for (int lineOffset = 0; lineOffset < yuyvLineSize; lineOffset += 4) {
                byte u = i420[i420UIndex++];
                byte v = i420[i420VIndex++];
                //偶数行数据赋值
                int yuyvOffset = yuyvLineStart + lineOffset;
                yuyv[yuyvOffset] = i420[i420YIndex];
                yuyv[yuyvOffset + 1] = u;
                yuyv[yuyvOffset + 2] = i420[i420YIndex + 1];
                yuyv[yuyvOffset + 3] = v;
                //奇数行数据赋值
                int yuyvNextLineOffset = yuyvLineStart + yuyvLineSize + lineOffset;
                yuyv[yuyvNextLineOffset] = i420[i420YIndex + width];
                yuyv[yuyvNextLineOffset + 1] = u;
                yuyv[yuyvNextLineOffset + 2] = i420[i420YIndex + width + 1];
                yuyv[yuyvNextLineOffset + 3] = v;

                i420YIndex += 2;
            }
            i420YIndex += width;
            yuyvLineStart += (width << 2);
        }
        return yuyv;
    }

i420转YuyvPlanar

public static byte[] i420ToYuyvPlanar(byte[] i420, int width, int height) {
        if (i420 == null || i420.length == 0 || i420.length != width * height * 3 / 2) {
            throw new IllegalArgumentException("invalid image params!");
        }
        byte[] yuyv = new byte[width * height * 2];
        int yuyvUIndex = width * height;
        int yuyvVIndex = width * height * 3 / 2;
        //Y planar
        System.arraycopy(i420, 0, yuyv, 0, width * height);

        int i420UIndex = width * height;
        int i420VIndex = width * height * 5 / 4;

        int i420UHeight = height/4;

        for(int i = 0; i<i420UHeight; i++) {
            // U plannar
            System.arraycopy(i420, i420UIndex+i*width, yuyv, yuyvUIndex+i*2*width, width);
            System.arraycopy(i420, i420UIndex+i*width, yuyv, yuyvUIndex+(i*2+1)*width, width);

            // V plannar
            System.arraycopy(i420, i420VIndex+i*width, yuyv, yuyvVIndex+i*2*width, width);
            System.arraycopy(i420, i420VIndex+i*width, yuyv, yuyvVIndex+(i*2+1)*width, width);
        }


        return yuyv;
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。