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

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

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

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

前言

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

开发流程

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

  • 字符尺寸确定

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

  • 字符预处理

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

  • 灰度值映射

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

  • 纹理处理

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

  • 性能优化

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

  • 纹理分辨率调整

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

  • fragment shader实现细节

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

    #version 450 core
    out 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/

    你可能感兴趣的文章
    Mysql8 数据库安装及主从配置 | Spring Cloud 2
    查看>>
    mysql8 配置文件配置group 问题 sql语句group不能使用报错解决 mysql8.X版本的my.cnf配置文件 my.cnf文件 能够使用的my.cnf配置文件
    查看>>
    MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
    查看>>
    MYSQL8.0以上忘记root密码
    查看>>
    Mysql8.0以上重置初始密码的方法
    查看>>
    mysql8.0新特性-自增变量的持久化
    查看>>
    Mysql8.0注意url变更写法
    查看>>
    Mysql8.0的特性
    查看>>
    MySQL8修改密码报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
    查看>>
    MySQL8修改密码的方法
    查看>>
    Mysql8在Centos上安装后忘记root密码如何重新设置
    查看>>
    Mysql8在Windows上离线安装时忘记root密码
    查看>>
    MySQL8找不到my.ini配置文件以及报sql_mode=only_full_group_by解决方案
    查看>>
    mysql8的安装与卸载
    查看>>
    MySQL8,体验不一样的安装方式!
    查看>>
    MySQL: Host '127.0.0.1' is not allowed to connect to this MySQL server
    查看>>
    Mysql: 对换(替换)两条记录的同一个字段值
    查看>>
    mysql:Can‘t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock‘解决方法
    查看>>
    MYSQL:基础——3N范式的表结构设计
    查看>>
    MYSQL:基础——触发器
    查看>>