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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

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