• 使用 C# 创造 ASCII 艺术


    c24ea0a42212295e80026c37301d3b30.png

    你见过那些很酷的“字母”艺术吗?用一些英文字母和符号组成某种文字或图像的?有些人尝试逐个字母地创建这种艺术,但今天我们将自己实现它!

    什么是 ASCII 艺术?

    基本上,ASCII 艺术是一种基于文本的艺术形式。程序或文档中使用的艺术文字或文本,由取自 ASCII 字符的字符和符号组成。

    什么是ASCII:https://en.wikipedia.org/wiki/ASCII

    它是如何工作的?

    好问题!

    为了解释这一点,我们必须了解图像是由什么组成的。

    图像,更具体地说,数字图像由像素组成,基于该图像的分辨率。

    因此,分辨率为 400 * 600(高\宽)的图像有 240000 像素。像素是数字图像的最小组成部分。每个像素都可以包含有关该像素颜色的数据,像素有不同数量的位来表示它们,其中每个位代表一个颜色选项

    • 1 bpp,2^1 = 2 种颜色(单色)

    • 2 bpp,2^2 = 4 种颜色

    • 3 bpp,2^3 = 8 种颜色

    • 4 bpp, 2^4 = 16 色

    • 8 bpp,2^8 = 256 色

    • 16 bpp, 2^16 = 65,536 色(“ 高彩色 ”)

    • 24 bpp, 2^24 = 16,777,216 色(“真彩色”)

    高彩色:https://en.wikipedia.org/wiki/Highcolor

    真彩色:https://en.wikipedia.org/wiki/24-bit_color

    那么我们如何构造颜色呢?

    有多种方法可以使用颜色空间定义颜色,其中最流行的一种是 sRGB。

    sRGB 代表标准红绿蓝,是一种色彩空间,或一组特定颜色,由惠普和微软于 1996 年创建,目标是标准化电子产品所描绘的颜色。

    换句话说,红色、绿色和蓝色的组合将产生不同的颜色。每个值的范围可以在 0 到 255 之间,因此以颜色表示为例:

    (R:255,G:0,B:0) = 红色

    (R:0,G:255,B:0) = 绿色

    (R: 0,G:0,B:255) = 蓝色

    (R:255,G:255,B:255) = 白色

    (R:0,G:0,B:0) = 黑色

    (R:100,G:100 ,B:100) = 灰色

    让我们进入代码实现。

    将图像打印为 ASCII 艺术

    假设,我们想将此图像转换为 ASCII 艺术:

    010c262813270d99db31dffb9db1b081.png

    可爱的小狗

    请注意,我们有图片的某些部分较暗,有些部分较亮。这正是我们在创建 ASCII 艺术时想要模拟的,一些字符可以代表一个暗像素,例如空格“”或点“.”。有些可以代表一个亮像素,例如“@”或“W”,但我为什么要专门选择这些?这其实很容易理解,字母越密,在深色背景上会显得越亮对吧?

    所以让我们定义我们的“调色板”:

    string asciiChars = "  .,:ilwW@@";

    这些字母必须按它们的密度排序,才能正常工作。

    2680949972a3205c35dd0b7530163e22.png

    假设我们有一个像素,并且我们知道它是 RGB 值,我们如何将其转换为 ASCII 字符,如果我们查看它的灰度颜色,将更容易理解像素的亮或暗。灰度色调可以由 RGB 值的平均值生成。

    例如,红色 (255,0,0) 灰度表示为 (85,85,85)。

    从这部分开始,剩下要做的就是取平均值并在我们之前创建的字符数组中获取它的位置。

    因此,如果颜色平均值有[0,255]种可能,而ASCII字符只有[0,10]种可能,我们想要在我们选择的ASCII字符数组中取这个颜色值的相对部分,

    我们在字符数组中放入的字母越多,我们就会有更多的可能性来代表我们的亮度值。

    6864ac8c8b4654fa741489f4ff030488.png

    我不想表示出每个像素,因为像素太多了。所以我调整了图像的大小以匹配 130 像素的宽度。

    最终结果:

    d63b228c0c7c454ee895c35f54b7a1cc.png

    这太棒了!

    不过我还需要改变字体,使字母之间的间距均匀,并微调行高,以使图片显示在正确的尺寸,而不是看起来像被压扁了。

    它也适用于视频吗?

    然后我想到了,视频基本上是数字图像的集合!如果我修改我的代码,以从一个短的 mp4 视频文件中提取帧如何呢?

    这是可能的,我只需要找到一种方法来提取帧,并重用我的代码。于是我找到了一个名为 NuGet Gallery | Emgu.CV 图像处理库的跨平台 .NET 包装器。

    NuGet Gallery | Emgu.CV :https://www.nuget.org/packages/Emgu.CV/

    为了减少控制台写入闪烁,我收集了需要插入到字符串构建器对象中的每个字符,并且在完成处理每一帧的像素时,我将该 StringBuilder 值推送到控制台中。并将控制台光标定位到文本的开头

    2b0e4ff727cad4cf2fc6e18edbc8061c.png

    看看这个:

    3ff8816cc0feaecc06788ee349a7e5b1.gif

    是不是很酷!

    最后一步

    最后一步,我们可以实时解析视频吗?

    使用同一个库,可以轻松地将视频捕获设置为网络摄像头,并将自己视为一堆“W”和“@”和“。”

    01440ae5d7a33d99cc85ddfe3490e3bc.gif

    快乐学习!

    ☆ END ☆

    如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

    扫描二维码添加小编↓

    8e2e56b3a66523ac19cfb355a8f8cb20.png

  • 相关阅读:
    JS如何实现书签导入导出?我是这么做的
    【教程】Python科研数据可视化、MATLAB科研数据可视化
    【iOS ARKit】网络传输 ARWorldMap
    c#winform根据邮箱地址和密码一键发送email
    【视频图像篇】FastStone Capture屏幕长截图软件
    企业实战之阿里druid统一监控方案,你了解吗?
    基于JavaSwing开发图书销售管理系统 课程设计 大作业 毕业设计
    Linux--bash、fork、exec、进程替换相关命令
    macOS通过钥匙串访问找回WiFi密码的详细教程
    React基础入门知识铺垫
  • 原文地址:https://blog.csdn.net/woshicver/article/details/125532370