关于YUV420转RGB24
来源:互联网 发布:2016中国经济危机知乎 编辑:程序博客网 时间:2024/05/29 04:46
关于YUV的格式介绍,网上有很多相关的例子,这里介绍的主要是YUV420格式的图片文件转换为rgb24位图片的一个简单例子,至于后面拓展成视频的话个人认为是比较简单的,无非就是不断调用这个转码函数而已,这个程序是从之前网上下载的一个工程当中剥离出来的,关于这个简单例子,最主要的就是中间那部分的转换了,大家可以仔细看看,还有一点就是要好好了解一下YUV颜色空间和RGB颜色空间的具体概念,对理解代码也是很有帮助的,不过这个转码小例子的速度可能不是很高,因为要达到很高速率的话,就可以考虑采用汇编来写了,采用拓展指令集MMX来做,这种例子我们csdn网站就有人做出来了,大家可以搜一搜,作此文章用作笔记和广大程序员分享,如有什么建议或者错误的地方,欢迎大家指正,我们一起交流。
#include <stdio.h>#include <stdlib.h>/****************************************************************************** 功 能:将一个double类型的数据转换成一个小于0 - 255 之间的无符号整型 * 参 数:val I 输入的double数据* 返回值:转化后的unsigned char类型数据*******************************************************************************/unsigned char clip(double val){if (val > 255){return 255;}elseif (val < 0){return 0;}else{return (unsigned char)val;}}/******************************************************************************* 功 能:将YUV420文件转为RGB文件* 参 数:rgb_data O 存放转化后的RGB数据的缓冲区首地址 yuv_data I 存放转化前的YUV数据的缓冲区首地址 image_width I 图像的宽度 image_height I 图像的高度* 返回值:转化成功返回1,否则返回0******************************************************************************/int yuv420_2rgb(unsigned char *rgb_data, unsigned char *yuv_data, int image_width, int image_height){unsigned char y = 0;unsigned char u = 0;unsigned char v = 0;int r = 0;int g = 0;int b = 0;int c = 0;int d = 0;int e = 0;unsigned char *y_planar = NULL; //指向Y平面的指针unsigned char *u_planar = NULL; //指向U平面的指针unsigned char *v_planar = NULL; //指向V平面的指针 int image_size = image_height * image_width; //图像的尺寸int rgb_width; //RGB的宽度 int u_width; //U平面的宽度int u_size; //U平面的尺寸int offset = 0; //偏移量int i = 0;int j = 0;u_size = (image_size >> 2); //u平面的尺寸等于图像尺寸除以4y_planar = yuv_data;//y分量u_planar = yuv_data + image_size; //u分量= y分量偏移尺寸大小v_planar = u_planar + u_size;//V分量=u分量偏移1/4尺寸大小rgb_width = image_width * 3;//rgb一行的数据宽度u_width = (image_width >> 1);//U平面的宽度图像宽度除以2if ((rgb_data == NULL) || (yuv_data == NULL)){printf("the buffer is empty\n");return -1;}for (i = 0; i < image_height; i++){for (j = 0; j < image_width; j++){y = y_planar[image_width * i + j];offset = u_width * (i >> 1 ) + (j >> 1);u = u_planar[offset];v = v_planar[offset];c = y - 16;d = u - 128;e = v - 128;r = clip( (298 * c + 409 * e + 128) >> 8 );g = clip( (298 * c - 100 * d - 208 * e + 128) >> 8 );b = clip( (298 * c + 516 * d + 128) >> 8 );offset = rgb_width * (image_height - i -1) + j * 3;rgb_data[offset + 0] = b;rgb_data[offset + 1] = g ;rgb_data[offset + 2] = r;}}return 0;}int main(int argc, char *argv[]){FILE *yuv = NULL;FILE *rgb = NULL;int height = 640;int wide = 480; int yuv_size = height*wide*3/2;int rgb_size = height*wide*3;unsigned char * rgb_data = NULL;int n = 0;unsigned char *yuv_buffer = NULL;yuv_buffer = (unsigned char *)malloc(sizeof(unsigned char)*yuv_size);rgb_data = (unsigned char*)malloc(sizeof(unsigned char)*rgb_size);if (yuv_buffer == NULL){printf(" yuv_buffer malloc is fail\n");return 0;}if (rgb_data == NULL){printf(" rgb_data malloc is fail\n");return 0;}if ((yuv=fopen(argv[1],"r"))== NULL){printf("open yuv is fail\n");return 0;}if ((rgb=fopen(argv[2],"w"))== NULL){printf("open rgb is fail\n");return 0;}n = fread(yuv_buffer,1,yuv_size,yuv);printf("n = [%d]\n",n); yuv420_2rgb(rgb_data,yuv_buffer,height,wide);n = fwrite(rgb_data,1,rgb_size,rgb);printf("n ===== [%d]\n",n);fclose(yuv);fclose(rgb);free(rgb_data);free(yuv_buffer); return 0;}
0 0
- 关于YUV420转RGB24
- 关于YUV420转RGB24的一些思考
- rgb24转yuv420
- 平面YUV420转RGB24
- YUV(YUV422、YUV420) 转RGB24
- YUV420 && RGB24
- 平面YUV422转平面RGB24 平面YUV420转平面YUV422 平面YUV420转RGB24
- YUV420、YUV422、RGB24转换
- YUV420、YUV422、RGB24转换
- YUV420、YUV422、RGB24转换
- YUV420、YUV422、RGB24转换
- YUV420、YUV422、RGB24转换
- YUV420、YUV422、RGB24转换
- YUV420、YUV422、RGB24转换
- YUV420转换成RGB24
- RGB24转yuv420 高效率 且颜色没有失真
- 三种方式YUV420转RGB24/BGR24,实测可用
- yuv420和rgb24互相转换
- 模拟——Parencodings
- codeforces 15C Industrial Nim(NIM 博弈)
- 陽卦多陰章
- Android之网络下载与图片解码-----网络图片浏览器
- linux 内核分析之list_head
- 关于YUV420转RGB24
- 【HTML】统一file提交样式 input type=file浏览修改,不清空file值,提交表单
- 黑马程序员_NSNumber、NSValue、NSNull
- 03 单链表的实现
- 链表的应用:单元多项式的加法、减法、乘法
- hibernate 从数据库生成实体对象
- 如何设计上十亿的用户表
- NYOJ 483 Nightmare 【广搜】+【无标记】
- hdu1816 + POJ 2723开锁(二分+2sat)