我正在开发一个程序(C/C++),用户应该获取用户选择的图像并将其转换为 ASCII 艺术(使用 SQL)。到目前为止,我已经能够让用户选择图像并在窗口中以灰度显示该图像。
但是,我目前很难将 ASCII 字符排序为亮度级别数组,然后将单个字符与像素区域匹配。
我知道我需要使用“for”循环,但到目前为止我在互联网上找不到任何有用的东西。谢谢你:D
$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'.
这是从暗到亮的标准灰度(或相反,具体取决于您喜欢的显示颜色。)
为了节省您的时间,此特定渐变包含 69 个字符。
`.-':_,^=;><+!rc*/z?sLTv)J7(|Fi{C}fI31tlu[neoZ5Yxjya]2ESwqkP6h9d4VpOGbUAKXHm8RD#$Bg0MNWQ%&@
我发现 Ahsen Khan 的答案对于我的 Windows 控制台字体 (consolas) 来说并不完全准确,这产生了稍微偏离的结果。 我编写了一个程序,通过对每个像素的灰度值求和来分析和排序字符,从而产生了这个结果。不要忘记在开头加上空格。
字符也不会因黑暗而均匀分布(尽管我发现假设均匀分布的结果很好)。每个角色的黑暗度是:
[0, 0.0751, 0.0829, 0.0848, 0.1227, 0.1403, 0.1559, 0.185, 0.2183, 0.2417, 0.2571, 0.2852, 0.2902, 0.2919, 0.3099, 0.3192, 0.3232, 0.3294, 0.3384, 0.3609, 0.3619, 0.3667, 0.3737, 0.3747, 0.3838, 0.3921, 0.396, 0.3984, 0.3993, 0.4075, 0.4091, 0.4101, 0.42, 0.423, 0.4247, 0.4274, 0.4293, 0.4328, 0.4382, 0.4385, 0.442, 0.4473, 0.4477, 0.4503, 0.4562, 0.458, 0.461, 0.4638, 0.4667, 0.4686, 0.4693, 0.4703, 0.4833, 0.4881, 0.4944, 0.4953, 0.4992, 0.5509, 0.5567, 0.5569, 0.5591, 0.5602, 0.5602, 0.565, 0.5776, 0.5777, 0.5818, 0.587, 0.5972, 0.5999, 0.6043, 0.6049, 0.6093, 0.6099, 0.6465, 0.6561, 0.6595, 0.6631, 0.6714, 0.6759, 0.6809, 0.6816, 0.6925, 0.7039, 0.7086, 0.7235, 0.7302, 0.7332, 0.7602, 0.7834, 0.8037, 0.9999]
这些值按比例缩放,0 表示全黑色像素(即空格字符),0.9999 表示最亮(“@”)。
没有合理的方法可以做到这一点,现有的 ASCII-art 程序只是使用预定义的字符顺序。 IE。
char myASCII[] = " .,:ilwW";
ASCII 字符没有固有的灰度,因为这仅取决于它们在屏幕上的绘制方式 - 使用什么字体、大小、水平和垂直间距以及使用什么颜色。
不过:还是可以做出有根据的猜测。对于大多数字体来说,空格是“全白”,句号在大多数字体中是一个小点,逗号稍大一些,等等。您所需要的只是每个可显示字符的黑白像素的比率。
查找(或创建)您要使用的字体的位图版本或与其接近的版本。由于大多数 ASCII 字体实际上在设计上非常接近,您甚至可以使用简单的 8x8 位图字体(没有多少字体会具有比
!
“更重”的 W
- 如果您找到这样的字体,请查找其他)。当您将其用于 ASCII 艺术时,您可能只需要等宽字体。使用比例字体绘制 ASCII 艺术是可能的,但要困难得多。循环每个字符并计算黑色像素。通常,一个空格会有
0
,句号 1
,像 #
这样的东西会有 16 个左右。 (嘿看!这是你可以使用 for
循环的地方!)每个字符的精确灰度可以用
value/area
表示,其中area
是位图的整个大小。但你对绝对值不感兴趣!正常的 ASCII 范围不包含应为“全黑”的字符。要找出“相对”灰度,请将每个字符的值除以为整个字体找到的“最大”值。这样,空间将为 0
,“最大值”字符将为 1
,所有其他字符将具有介于两者之间的值。 (实际上,如果您的空格字符包含黑色像素,也请从初始值中减去这些像素。只是为了概述总体思路;您最好不要使用如此奇怪的字体。)
您最终将得到 95 个值 - 从 Space (#32) 到 Tilde (#126) 每一个值。如果您想在输出中使用所有字符,那么您就可以开始了。按灰度等级对字符进行排序。对于每个灰色输入像素(级别从 0 到 255),将其除以 255,使其处于与字符映射值相同的范围内。然后打印与其级别最接近的字符。 (这是最直接的方法,但可以通过多种方式进行优化。)如果您想将灰度限制为较小的值/字符范围,请使用最接近您想要的级别的值构建一个较小的数组。例如,如果您想要 16 级灰度,请找到最接近 0、1/15、2/15 ... 15/15 的字符。
另请参阅
我对相关问题的回答