OpenGL ES:rgb转换yuv

qq群里有兄弟讨论使用gles rgb转换yuv问题,刚刚好前段时间我花了两天时间抄袭修改过,代码简单粗暴,如下:

const GLchar *strVertexShaderRgb2Yuv =
    "attribute vec4 position;\n"
    "attribute vec4 inputTextureCoordinate;\n"
    "\n"
    "varying vec2 textureCoordinate;\n"
    "\n"
    "void main()\n"
    "{\n"
    "    gl_Position = position;\n"
    "    textureCoordinate = inputTextureCoordinate.xy;\n"
    "}\n";

const GLchar *strFragmentShaderRgb2Yuv =
    "precision highp float;\n"
    "\n"
    "varying vec2 textureCoordinate;\n"
    "\n"
    "uniform sampler2D inputImageTexture;\n"
    "uniform float uWidth;\n"
    "uniform float uHeight;\n"
    "\n"
    "float cY(float x, float y)\n"
    "{\n"
    "    vec4 c = texture2D(inputImageTexture, vec2(x, y));\n"
    "    return c.r * 0.257 + c.g * 0.504 + c.b * 0.098 + 0.0625;\n"
    "}\n"
    "\n"
    "vec4 cC(float x, float y, float dx, float dy)\n"
    "{\n"
    "    vec4 c0 = texture2D(inputImageTexture, vec2(x, y));\n"
    "    vec4 c1 = texture2D(inputImageTexture, vec2(x + dx, y));\n"
    "    vec4 c2 = texture2D(inputImageTexture, vec2(x, y + dy));\n"
    "    vec4 c3 = texture2D(inputImageTexture, vec2(x + dx, y + dy));\n"
    "    return (c0 + c1 + c2 + c3) / 4.0;\n"
    "}\n"
    "\n"
    "float cU(float x, float y, float dx, float dy)\n"
    "{\n"
    "    vec4 c = cC(x, y, dx, dy);\n"
    "    return -0.148 * c.r - 0.291 * c.g + 0.439 * c.b + 0.5000;\n"
    "}\n"
    "\n"
    "float cV(float x, float y, float dx, float dy)\n"
    "{\n"
    "    vec4 c = cC(x, y, dx, dy);\n"
    "    return 0.439 * c.r - 0.368 * c.g - 0.071 * c.b + 0.5000;\n"
    "}\n"
    "\n"
    "vec4 calculateY(float x, float y, float dx, float dy)\n"
    "{\n"
    "    vec4 c = vec4(0.0);\n"
    "    c[0] = cY(x, y);\n"
    "    c[1] = cY(x + 1.0 * dx, y);\n"
    "    c[2] = cY(x + 2.0 * dx, y);\n"
    "    c[3] = cY(x + 3.0 * dx, y);\n"
    "    return c;\n"
    "}\n"
    "\n"
    "vec4 calculateU(float x, float y, float dx, float dy)\n"
    "{\n"
    "    vec4 c = vec4(0.0);\n"
    "    c[0] = cU(x, y, dx, dy);\n"
    "    c[1] = cU(x + 2.0 * dx, y, dx, dy);\n"
    "    c[2] = cU(x + 4.0 * dx, y, dx, dy);\n"
    "    c[3] = cU(x + 6.0 * dx, y, dx, dy);\n"
    "    return c;\n"
    "}\n"
    "\n"
    "vec4 calculateV(float x, float y, float dx, float dy)\n"
    "{\n"
    "    vec4 c = vec4(0.0);\n"
    "    c[0] = cV(x, y, dx, dy);\n"
    "    c[1] = cV(x + 2.0 * dx, y, dx, dy);\n"
    "    c[2] = cV(x + 4.0 * dx, y, dx, dy);\n"
    "    c[3] = cV(x + 6.0 * dx, y, dx, dy);\n"
    "    return c;\n"
    "}\n"
    "\n"
    "void main()\n"
    "{\n"
    "    if (textureCoordinate.y > 0.375) {\n"
    "       return;\n"
    "    }\n"
    "\n"
    "    float y4xSum = uWidth * uHeight / 4.0;\n"
    "    float u4xSum = uWidth * uHeight / 16.0;\n"
    "    float v4xSum = uWidth * uHeight / 16.0;\n"
    "    float yuv4xOffset = floor(textureCoordinate.y * uHeight) * uWidth + floor(textureCoordinate.x * uWidth);\n"
    "\n"
    "    if (yuv4xOffset < y4xSum) {\n"
    "        float yOffset = yuv4xOffset * 4.0 + 1.0;\n"
    "        float yX = floor(mod(yOffset, uWidth));\n"
    "        float yY = floor(yOffset / uWidth);\n"
    "        yY = uHeight - yY;\n"
    "        gl_FragColor = calculateY(yX / uWidth, yY / uHeight, 1.0 / uWidth, 1.0 / uHeight);\n"
    "    } else if (yuv4xOffset < (y4xSum + u4xSum)) {\n"
    "        float uOffset = (yuv4xOffset - y4xSum) * 4.0 + 1.0;\n"
    "        float uX = floor(mod(uOffset, uWidth / 2.0)) * 2.0;\n"
    "        float uY = floor(uOffset / (uWidth / 2.0)) * 2.0;\n"
    "        uY = uHeight - uY - 1.0;\n"
    "        gl_FragColor = calculateU(uX / uWidth, uY / uHeight, 1.0 / uWidth, 1.0 / uHeight);\n"
    "    } else if (yuv4xOffset < (y4xSum + u4xSum + v4xSum)) {\n"
    "        float vOffset = (yuv4xOffset - y4xSum - u4xSum) * 4.0 + 1.0;\n"
    "        float vX = floor(mod(vOffset, uWidth / 2.0)) * 2.0;\n"
    "        float vY = floor(vOffset / (uWidth / 2.0)) * 2.0;\n"
    "        vY = uHeight - vY - 1.0;\n"
    "        gl_FragColor = calculateV(vX / uWidth, vY / uHeight, 1.0 / uWidth, 1.0 / uHeight);\n"
    "    }\n"
    "}\n";

缺点

  • 空间浪费:只用了 framebuffer 3/8
  • 分辨率限制为8的倍数
  • rgb到yuv的转换公式写死,不够灵活

参考文章:湖广午王的博客该链接已失效,可见(https://www.jishux.com/p/518a2b6653e09e43)
YUV to RGB Conversion

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 由于H.264等压缩算法都是在YUV的颜色空间上进行的,所有在进行压缩前,首先要进行颜色空间的转换。如果摄像头采集...
    眷卿三世阅读 14,643评论 2 6
  • 前一阵子在梳理以前文章的时候,发现自己虽然总结了各种视音频应用程序,却还缺少一个适合无视音频背景人员学习的“最基础...
    视频音频小白阅读 6,210评论 1 3
  • RGB和YUV 多媒体编程 一、概念 1.什么是RGB? 对一种颜色进行编码的方法统称为“颜色空间”或“色域”。用...
    流年易逝_李阅读 14,949评论 0 6
  • 今天在郑州的学习结束了,回想这几天的心灵路程,收获了很多!以前,关于团队这个词,有很多的理解,但都只限于字...
    凤舞九天_b849阅读 1,643评论 0 0
  • 我是一直对学习感兴趣,并且从来没有对它厌烦过,乐此不疲—— 没有谁教育,不需要谁灌输,而且我是越是考完试,越要学习...
    张娟丽2210阅读 2,047评论 0 1

友情链接更多精彩内容