java上argb转yuv422数据

public byte[] rgb2YCbCr422(int[] pixels, int width, int height) {
        int len = width * height;
        int index = 0;
        //yuv格式数组大小,y亮度占len长度,u,v各占len/4长度。
        byte[] yuv = new byte[len * 2];
        int y, u, v, y1, u1, v1;
        int rgb, b, g, r, a;
        for (int i = 0; i < height * width; i++) {
            a = pixels[i] >>> 24;

            //屏蔽ARGB的透明度值
            rgb = pixels[i] & 0x00FFFFFF;
            //像素的颜色顺序为bgr,移位运算。
            b = rgb & 0xFF;
            g = (rgb >> 8) & 0xFF;
            r = (rgb >> 16) & 0xFF;
            //套用公式
            y = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
            u = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
            v = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;

            //调整
        /*    y = (y > 255 ? 255 : y);
            u = u < 0 ? 0 : (u > 255 ? 255 : u);
            v = v < 0 ? 0 : (v > 255 ? 255 : v);*/

            rgb = pixels[i++] & 0x00FFFFFF;
            b = rgb & 0xFF;
            g = (rgb >> 8) & 0xFF;
            r = (rgb >> 16) & 0xFF;

            y1 = ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
            u1 = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
            v1 = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;

            //调整
            y1 = (y1 > 255 ? 255 : y1);
            u1 = u1 < 0 ? 0 : (u1 > 255 ? 255 : u1);
            v1 = v1 < 0 ? 0 : (v1 > 255 ? 255 : v1);

            yuv[index++] = (byte) y;
            if(a==0)
            {
                yuv[index++] = 0;
            }
            else
            {
                //两个rgb像素点的u分量合并除以2得出新的yuv的U分量
                yuv[index++] = (byte) ((u + u1) >> 1);
            }
            yuv[index++] = (byte) y1;
            //屏蔽透明色,因为yuv是没有透明色的,所以要把argb的透明色给屏蔽掉。
            //屏蔽透明色还有点问题,需要处理。
            if(a==0)
            {
                yuv[index++] = 0;
            }
            else
            {
                yuv[index++] = (byte) v;
            }
        }
        return yuv;
    }

上面之所以一次算出2个int的argb里的RGB值,转换成4个byte的yuv值,是因为一个ARGB值,可以分别得出一个R、G、B数值出来。这个R、G、B可以转成对应的Y、U、V的值,但是一个rgb的像素点,对应两个yuv的字节,这里有3个值,一次填不下,所以就算出两个rgb像素点出来,然后将其中的两个u合并,再丢掉一个相临的V值,就可以得到2个yuv像素点的4个字节了。

 

使用上面函数的方法:

这个bitmap是读取的一张jpg的图片,保存在bitmap变量里。

bitmap.getPixels(regaArr[i], 0 , w, i * w, 0, w, h);

byte [] yuv = rgb2YCbCr422_3(regaArr[i], w, h);

 

 

yuv颜色编码的详细解析,有一篇博客 说得不错,大家可以参考下:

https://www.jianshu.com/p/a91502c00fb0

 

点赞