YUV图像格式转换方法实践

本文详细介绍了I420与UYVY两种色彩空间格式,并提供了从I420到NV12/NV21以及从UYVY到NV12/NV21的转换方法与实现代码。

一 I420转NV12

1.I420格式

(1)I420是每四个Y共用一组UV,如果一帧I420图像宽带是width,高度是height,1个像素占1个字节,那么共有width✖height个Y,U和V都是width✖height / 4个,因此一帧I420图像占用字节数是width✖height✖3/2。

(2)I420是先存完所有Y后,在接着存完U,最后存V。

2.NV12格式

(1)NV12是每四个Y共用一组UV,如果一帧NV12图像宽带是width,高度是height,1个像素占1个字节,那么共有width✖height个Y,U和V都是width✖height / 4个,因此一帧I420图像占用字节数是width✖height✖3/2。

(2)NV12是先存完所有Y后,随后U、V交替存储。

3.转换方法

(1)将一帧I420图像中所有Y拷贝到NV12数据区,将一帧I420图像中所有U和V交替拷贝到NV12数据区。

(2)代码:

bool convert_i420_nv12(const char *i420_file_path, size_t width, size_t height, const char *nv12_file_path) {
    if (!i420_file_path || !nv12_file_path) {
        return false;
    }
    FILE *fp = fopen(i420_file_path, "rb");
    if (!fp) {
        return false;
    }
    fseek(fp, 0, SEEK_END);
    size_t file_size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    size_t y_size = width * height;
    size_t uv_size = y_size / 4;
    if (file_size != (y_size + uv_size * 2)) {
        fclose(fp);
        return false;
    }
    char *i420_content = (char *)malloc(sizeof(char) * file_size);
    if (!i420_content) {
        fclose(fp);
        return false;
    }
    if (file_size != fread(i420_content, 1, file_size, fp)) {
        free(i420_content);
        fclose(fp);
        return false;
    }
    fclose(fp);
    // convert i420 to nv12
    char *nv12_content = (char *)malloc(sizeof(char) * file_size);
    if (!nv12_content) {
        free(i420_content);
        return false;
    }
    // copy y channel
    memcpy(nv12_content, i420_content, y_size);
    // copy uv channel
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值