博客
关于我
使用OpenGL实现ASCII Art滤镜
阅读量:757 次
发布时间:2019-03-22

本文共 1795 字,大约阅读时间需要 5 分钟。

OpenGL实现的ASCII Art滤镜开发实践

近期,我尝试将经典的ASCII Art滤镜从CPU版本迁移到OpenGL版本。该滤镜旨在将输入图像转换为基于ASCII字符的艺术效果。现将本次开发过程总结如下:

前言

基于之前的CPU版本实现,滤镜的效率相对较低,尤其在处理视频时会产生明显卡顿。为提高效率,将滤镜重构为基于OpenGL的实现。

开发流程

本次开发与CPU版本的滤镜流程大致相同,但在实现细节上进行了优化:

  • 字符尺寸确定

    首先需要根据选用的字体确定单元网格的尺寸。例如,设置常用宽度和高度,确保字符不会过大或过小导致效果不佳。

  • 字符预处理

    CPU版本中会绘制每个可用字符到空白图像上并计算其平均灰度值。本次流程相同,但将其作为预处理阶段进行优化。

  • 灰度值映射

    根据每个字符的平均灰度值建立映射表,值域在0-255之间。输入图像的每个像素会被灰度化,并根据映射表获取对应字符。

  • 纹理处理

    在OpenGL中,通过设置顶点着色器和处理片段程序(Fragment Program),将输入图像纹理划分为单元网格。每个网格根据中央灰度值获取对应字符,并在特定位置进行选择和显示。

  • 性能优化

    通过调用texture函数启用高效纹理访问,同时利用浮点运算处理像素坐标,为每个像素找出准确字符位置,明显提升了处理速度。

  • 纹理分辨率调整

    根据当前屏幕分辨率调整网格大小,确保字符清晰可见。整体流程保持与CPU版本一致,但图形处理更高效。

  • fragment shader实现细节

    片段着色器代码实现如下:

    #version 450 coreout vec4 fragColor;in vec2 texCoord;uniform float charWidth;uniform float charHeight;uniform sampler2D imageTexture;uniform sampler2D asciiTexture;void main() {    // 网格尺寸设置    float gridWidth = charWidth;    float gridHeight = charHeight;    // 确定当前像素的网格位置    int xGrid = int(texCoord.x / gridWidth);    int yGrid = int(texCoord.y / gridHeight);    // 计算在网格内的绝对位置    float xDelta = texCoord.x - xGrid * gridWidth;    float yDelta = texCoord.y - yGrid * gridHeight;    // 获取当前像素的原始颜色    vec4 texColor = texture(imageTexture, vec2(xGrid * gridWidth, yGrid * gridHeight));    // 灰度值计算 (RGB到灰度)    float gray = (texColor.x * 0.299) + (texColor.y * 0.587) + (texColor.z * 0.114);    // 根据灰度值获取字符索引    int index = int(gray / (1.0 / 255.0));    // 在字符纹理中定位字符并获取颜色    float charX = 1.0 / 256.0 * (index + (xDelta / gridWidth));    float charY = yDelta / gridHeight;    fragColor = texture(asciiTexture, vec2(charX, charY));}

    性能表现

    相当于基于OpenGL的实现表现出色。在窗口缩放或调整大小时,几乎不引起延迟,连续重绘具有椭圆曲线形状。

    存在的问题

    该实现在终端显示方面存在局限性。由于OpenGL依赖图形显存,无法将生成的字符艺术发送回终端显示域。因此,这一实现在特定场景下仍需改进。

    总体来看,基于OpenGL的滤镜实现在性能和流程上均优于CPU版本。尽管存在少量局限,但整体效果令人满意。期待对相关技术进行深入研究,不断提升滤镜表现。

    转载地址:http://rmpwk.baihongyu.com/

    你可能感兴趣的文章
    mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
    查看>>
    MySql 查询以逗号分隔的字符串的方法(正则)
    查看>>
    MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
    查看>>
    mysql 查询数据库所有表的字段信息
    查看>>
    【Java基础】什么是面向对象?
    查看>>
    mysql 查询,正数降序排序,负数升序排序
    查看>>
    MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
    查看>>
    mysql 死锁 Deadlock found when trying to get lock; try restarting transaction
    查看>>
    mysql 死锁(先delete 后insert)日志分析
    查看>>
    MySQL 死锁了,怎么办?
    查看>>
    MySQL 深度分页性能急剧下降,该如何优化?
    查看>>
    MySQL 深度分页性能急剧下降,该如何优化?
    查看>>
    MySQL 添加列,修改列,删除列
    查看>>
    mysql 添加索引
    查看>>
    MySQL 添加索引,删除索引及其用法
    查看>>
    mysql 状态检查,备份,修复
    查看>>
    MySQL 用 limit 为什么会影响性能?
    查看>>
    MySQL 用 limit 为什么会影响性能?有什么优化方案?
    查看>>
    MySQL 用户权限管理:授权、撤销、密码更新和用户删除(图文解析)
    查看>>
    mysql 用户管理和权限设置
    查看>>