简单YUV数据转换
  z5VK1pTXrGNK 2023年11月02日 64 0


YUV是一种亮度信号Y和色度信号U、V是分离的色彩空间,它主要用于优化彩色视频信号的传输,使其向后相容老式黑白电视。其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V”表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。 YUV格式分为两种类型:Packed类型和Planar类型。 

1、Packed类型:是将YUV分量存在在同一个数组中,每个像素点的Y、U、V是连续交错存储的;

2、Planar类型:是将YUV分量分别存放到三个独立的数组中,且先连续存储所有像素点的Y,紧接着存储所有像素点的U,最后是所有像素点的V。

一、将NV21转Yuv420p

// YYYYYYYY VUVU  --> YYYYYYYY UVUV
// 将NV21转换为Yuv420sp
public static byte[] nv21ToYuv420sp(byte[] src, int width, int height) {
    int yLength = width * height;
    int uLength = yLength / 4;
    int vLength = yLength / 4;
    int frameSize = yLength + uLength + vLength;
    byte[] yuv420sp = new byte[frameSize];
    // Y分量
    System.arraycopy(src, 0, yuv420sp, 0, yLength);
    for (int i = 0; i < yLength/4; i++) {
        // U分量
        yuv420sp[yLength + 2 * i] = src[yLength + 2*i+1];
        // V分量
        yuv420sp[yLength + 2*i+1] = src[yLength + 2*i];
    }
    return yuv420sp;
}

二、将YUV420SemiPlanner转换为NV21

// YYYYYYYY UVUV(yuv420sp)--> YYYYYYYY VUVU(nv21)
// 将YUV420SemiPlanner转换为NV21
public static byte[] yuv420spToNV21(byte[] src, int width, int height) {
    int yLength = width * height;
    int uLength = yLength / 4;
    int vLength = yLength / 4;
    int frameSize = yLength + uLength + vLength;
    byte[] nv21 = new byte[frameSize];
    // Y分量
    System.arraycopy(src, 0, nv21, 0, yLength);
    for (int i = 0; i < yLength/4; i++) {
        // U分量
        nv21[yLength + 2*i +1] = src[yLength+2*i];
        // V分量
        nv21[yLength + 2*i] = src[yLength + 2*i + 1];
    }
    return nv21;
}

 三、将YUV420Planner(I420)转换为NV21

// YYYYYYYY UU VV --> YYYYYYYY VUVU
// 将YUV420Planner(I420)转换为NV21
public static byte[] yuv420pToNV21(byte[] src, int width, int height) {
    int yLength = width * height;
    int uLength = yLength / 4;
    int vLength = yLength / 4;
    int frameSize = yLength + uLength + vLength;
    byte[] nv21 = new byte[frameSize];
 
    System.arraycopy(src, 0, nv21, 0, yLength); // Y分量
    for (int i = 0; i < yLength / 4; i++) {
        // U分量
        nv21[yLength + 2*i + 1] = src[yLength + i];
        // V分量
        nv21[yLength + 2*i] = src[yLength + uLength + i];
    }
    return nv21;
}

四、将nv21转换为yuv420p(I420)

// YYYYYYYY VUVU ---> YYYYYYYY UU VV
// 
public static byte[] nv21ToYuv420p(byte[] src, int width, int height) {
    int yLength = width * height;
    int uLength = yLength / 4;
    int vLength = yLength / 4;
    int frameSize = yLength + uLength + vLength;
    byte[] yuv420p = new byte[frameSize];
    // Y分量
    System.arraycopy(src, 0, yuv420p, 0, yLength);
    for (int i = 0; i < yLength/4; i++) {
        // U分量
        yuv420p[yLength + i] = src[yLength + 2*i + 1];
        // V分量
        yuv420p[yLength + uLength + i] = src[yLength + 2*i];
    }
    return yuv420p;
}

 五、将YV12转换为NV21

// YYYYYYYY VV UU --> YYYYYYYY VUVU
// 将YV12转换为NV21
public static byte[] yv12ToNV21(byte[] src, int width, int height) {
    int yLength = width * height;
    int uLength = yLength / 4;
    int vLength = yLength / 4;
    int frameSize = yLength + uLength + vLength;
    byte[] nv21 = new byte[frameSize];
 
    System.arraycopy(src, 0, nv21, 0, yLength); // Y分量
    for (int i = 0; i < yLength / 4; i++) {
        // U分量
        nv21[yLength + 2*i + 1] = src[yLength + vLength + i];
        // V分量
        nv21[yLength + 2*i] = src[yLength + i];
    }
    return nv21;
}

五种数据互相转换。

                                                                                     -END

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  xaeiTka4h8LY   2024年05月17日   56   0   0 数据库JavaSQL
z5VK1pTXrGNK