这段时间一直在搞视频格式的转换问题,终于最近将一个图片的YUV格式转RGB格式转换成功了。下面就来介绍一下:
由于我的工程是在vs2008中的,其中包含一些相关头文件和库,所以下面只是列出部分核心代码,并不是全部代码。
1、下载一个包含YUV数据的文件也可以自己制作一个该文件
下载地址:
YUV数据文件
2、读入YUV数据文件中的yuv数据:
关键代码如下:
2.1读文件代码
- unsigned char * readYUV(char *path)
- {
- FILE *fp;
- unsigned char * buffer;
- long size = 1280 * 720 * 3 / 2;
- if((fp=fopen(path,"rb"))==NULL)
- {
- printf("cant open the file");
- exit(0);
- }
- buffer = new unsigned char[size];
- memset(buffer,'\0',size);
- fread(buffer,size,1,fp);
- fclose(fp);
- return buffer;
- }
2.2读入数据,并将YUV数据分别制作成3个纹理
- GLuint texYId;
- GLuint texUId;
- GLuint texVId;
- void loadYUV(){
- int width ;
- int height ;
- width = 640;
- height = 480;
- unsigned char *buffer = NULL;
- buffer = readYUV("1.yuv");
- glGenTextures ( 1, &texYId );
- glBindTexture ( GL_TEXTURE_2D, texYId );
- glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
- glGenTextures ( 1, &texUId );
- glBindTexture ( GL_TEXTURE_2D, texUId );
- glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer + width * height);
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
- glGenTextures ( 1, &texVId );
- glBindTexture ( GL_TEXTURE_2D, texVId );
- glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer + width * height * 5 / 4 );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
- }
上述代码中1.yuv就是YUV数据文件
3、将纹理传入OpenGL shader进行显示
- </pre></h1><h2>3.1 顶点shader和片段shader代码</h2><div><pre name="code" class="cpp"> GLbyte vShaderStr[] =
- "attribute vec4 vPosition; \n"
- "attribute vec2 a_texCoord; \n"
- "varying vec2 tc; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = vPosition; \n"
- " tc = a_texCoord; \n"
- "} \n";
-
- GLbyte fShaderStr[] =
- "precision mediump float;\n"
- "uniform sampler2D tex_y; \n"
- "uniform sampler2D tex_u; \n"
- "uniform sampler2D tex_v; \n"
- "varying vec2 tc; \n"
- "void main() \n"
- "{ \n"
- " vec4 c = vec4((texture2D(tex_y, tc).r - 16./255.) * 1.164);\n"
- " vec4 U = vec4(texture2D(tex_u, tc).r - 128./255.);\n"
- " vec4 V = vec4(texture2D(tex_v, tc).r - 128./255.);\n"
- " c += V * vec4(1.596, -0.813, 0, 0);\n"
- " c += U * vec4(0, -0.392, 2.017, 0);\n"
- " c.a = 1.0;\n"
- " gl_FragColor = c;\n"
- "} \n";
- </pre></h1><h2>3.1 顶点shader和片段shader代码</h2><div><pre name="code" class="cpp"> GLbyte vShaderStr[] =
- "attribute vec4 vPosition; \n"
- "attribute vec2 a_texCoord; \n"
- "varying vec2 tc; \n"
- "void main() \n"
- "{ \n"
- " gl_Position = vPosition; \n"
- " tc = a_texCoord; \n"
- "} \n";
- GLbyte fShaderStr[] =
- "precision mediump float;\n"
- "uniform sampler2D tex_y; \n"
- "uniform sampler2D tex_u; \n"
- "uniform sampler2D tex_v; \n"
- "varying vec2 tc; \n"
- "void main() \n"
- "{ \n"
- " vec4 c = vec4((texture2D(tex_y, tc).r - 16./255.) * 1.164);\n"
- " vec4 U = vec4(texture2D(tex_u, tc).r - 128./255.);\n"
- " vec4 V = vec4(texture2D(tex_v, tc).r - 128./255.);\n"
- " c += V * vec4(1.596, -0.813, 0, 0);\n"
- " c += U * vec4(0, -0.392, 2.017, 0);\n"
- " c.a = 1.0;\n"
- " gl_FragColor = c;\n"
- "} \n";
上述片段shader中就是根据yuv转rgb的公式得来的。也就是说是在shader中实现转换的。
4、显示结果
结果如下:
注意:该shader是OpenGL ES格式的,与OpenGL格式的shader有一点差别。
其它链接:http://www.cnblogs.com/weinyzhou/archive/2012/07/07/2592453.html?ADUIN=517436588&ADSESSION=1405491322&ADTAG=CLIENT.QQ.5329_.0&ADPUBNO=26349