博客
关于我
使用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中interactive_timeout和wait_timeout的区别
    查看>>
    mysql中int、bigint、smallint 和 tinyint的区别、char和varchar的区别详细介绍
    查看>>
    mysql中json_extract的使用方法
    查看>>
    mysql中json_extract的使用方法
    查看>>
    mysql中kill掉所有锁表的进程
    查看>>
    mysql中like % %模糊查询
    查看>>
    MySql中mvcc学习记录
    查看>>
    mysql中null和空字符串的区别与问题!
    查看>>