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

 

在Android开发中,处理YUV图像是一种常见的图像处理操作。YUV是图像处理中常用的一种颜色编码方法,特别是在图像压缩和视频通信中。在Java中对YUV图像进行缩小操作,通常需要先将YUV数据换为可识别的图像格式,然后进行缩放处理。 以下是一个简单的Java代码示例,展示了如何在Android中使用javaYUV图像进行缩小: ```java import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; public class YuvImage缩放 { /** * 缩放YUV图像 * * @param yuvData YUV数据 * @param width 图像宽度 * @param height 图像高度 * @param newWidth 新的宽度 * @param newHeight 新的高度 * @return 缩放后的Bitmap对象 */ public Bitmap scaleYuvToBitmap(byte[] yuvData, int width, int height, int newWidth, int newHeight) { // 创建YUV格式的Bitmap Bitmap yuvBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); // 将YUV数据复制到Bitmap中 yuvBitmap.copyPixelsFromBuffer(ByteBuffer.wrap(yuvData)); // 创建一个缩放矩阵 Matrix matrix = new Matrix(); // 设置缩放比例 matrix.postScale((float) newWidth / width, (float) newHeight / height); // 创建一个新的Bitmap,用于存放缩放后的图像 Bitmap scaledBitmap = Bitmap.createBitmap( yuvBitmap, 0, 0, width, height, matrix, true); // 释放原始YUV Bitmap资源 yuvBitmap.recycle(); return scaledBitmap; } } ``` 在这个例子中,我们首先创建了一个YUV格式的`Bitmap`对象,并通过`copyPixelsFromBuffer`方法将YUV数据填充到这个`Bitmap`中。然后,我们创建了一个`Matrix`对象来设置缩放比例,并使用`Bitmap.createBitmap`方法来创建一个新的缩放后的`Bitmap`。最后,我们回收了原始的YUV `Bitmap`资源。 请注意,这个示例代码仅用于说明如何在Java中使用`Matrix`对`Bitmap`进行缩放,并没有包含从相机或其他来源获取YUV数据的完整过程。在实际应用中,你可能需要根据具体的数据格式(如NV21等)来调整代码,以正确地处理YUV数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值