IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> YUV与RGB相互转换 -> 正文阅读

[移动开发]YUV与RGB相互转换

Android相机yuv输出格式是420sp,MediaCodec硬编码通常也是yuv420sp,因此yuv420sp与rgb之间的转换较为常用,这里记录一下:

转换公式按照

yuv2rgb:? ?\\R=Y+1.403(V-128) \\ G=Y-0.344(U-128)-0.714(V-128) \\ B=Y+1.770(U-128)

?rgb2yvv:??\\Y=0.299R+0.587G+0.114B \\U=0.5R-0.419G-0.081B+128 \\V=-0.169R-0.331G+0.5B+128

rgb转yuv420sp(YYYYUVUV),每逢偶数行及偶数列取一次UV数据:

/**
     * @param yuv420sp target to save yuv data, the length should be at least width*height*1.5
     * @param rgb rgb data, every 3 bytes as a color, without alpha
     * @param width image width
     * @param height image height
     * @param stride The number of bytes to skip between rows.
     *               Normally this value will be the same as the width, but it may be larger sometimes
     */
    void rgb2YUV420sp(byte[] yuv420sp, byte[] rgb, int width, int height, int stride) {

        int frameSize = width * height;
        int yIndex = 0;
        int uvIndex = frameSize;

        int r, g, b, y, u, v;
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {

                int index = (i * stride + j) * 3;
                r = rgb[index++];
                g = rgb[index++];
                b = rgb[index];

                //RGB to YUV
                y = (76 * r + 150 * g + 29 * b + 128) >> 8;//y=0.299r+0.587g+0.114b

                yuv420sp[yIndex++] = (byte) (y < 0 ? 0 : y > 255 ? 255 : y);
                if (i % 2 == 0 && j % 2 == 0) {
                    u = ((-43 * r - 84 * g + 128 * b + 128) >> 8) + 128;//u=-0.169r-0.331g+0.5b+128
                    v = ((128 * r - 107 * g - 20 * b + 128) >> 8) + 128;//v=0.5r-0.419g-0.081b+128
                    yuv420sp[uvIndex++] = (byte) (v < 0 ? 0 : v > 255 ? 255 : v);
                    yuv420sp[uvIndex++] = (byte) (u < 0 ? 0 : u > 255 ? 255 : u);
                }
            }
        }
    }

下面是yuv420sp转rgb的

/**
     * Convert image format from i420sp(NV12) to ARGB
     *
     * @param pixels array to save pixels, it's length should be no less than width*height
     * @param data   YUV data(like YYYYUVUV) with <I>length=1.5*width*height</I>,
     *               <b>or</b> gray image that has only Y plane with <I>length=width*height</I>
     * @param width  width of image
     * @param height height of image
     */
    public void convertYuv2Rgb(int[] pixels, byte[] data, int width, int height) {
        int len = width * height;
        if (len == data.length) {//only has Y
            for (int i = 0; i < len; i++) {
                int y = data[i] & 0xff;
                pixels[i] = Color.argb(255, y, y, y);
            }
        } else {
            int[] rgb = new int[3];
            int y, u, v;
            int pixIndex = 0;
            int yStart, uvStart;
            for (int i = 0; i < height; i++) {
                yStart = i * width;//use stride, if stride!=width
                //uv start from width*height, every 2 columns share 1 row of uv data with stride=width
                uvStart = len + (i >> 1) * width;
                for (int j = 0; j < width; j++) {
                    y = data[yStart + j] & 0xff;
                    int uIndex = uvStart + (j >> 1 << 1);//every 2 pixels shared a group of uv
                    u = (data[uIndex++] & 0xff) - 128;
                    v = (data[uIndex] & 0xff) - 128;
                    rgb[0] = y + (v * 359 >> 8);//r=y+1.403v
                    rgb[1] = y - (u * 88 >> 8) - (v * 182 >> 8);//g=y-0.344u-0.714v
                    rgb[2] = y + (u * 453 >> 8);//b=y+1.77u
                    for (int k = 0; k < 3; k++) {//rgb value should be 0-255
                        rgb[k] = rgb[k] > 255 ? 255 : rgb[k] < 0 ? 0 : rgb[k];
                    }
                    pixels[pixIndex++] = Color.argb(255, rgb[0], rgb[1], rgb[2]);
                }
            }
        }
    }

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-10 23:09:44  更:2021-08-10 23:10:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 10:36:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码