Java:Java 中的 ASCII 艺术生成器






4.50/5 (2投票s)
Java 中的 ASCII 艺术生成器
引言
ASCII 艺术是一种使用 ASCII 标准中的可打印字符来创作视觉艺术的技术。 在历史上,当打印机缺乏图形功能时,它就有了用处,并且在嵌入图像尚未成为可能时,它也被用于电子邮件。 我向您展示一个用 Java 编写的非常简单的 ASCII 艺术生成器,具有可配置的字体和对比度。 由于它是在周末的几个小时内构建的,因此它不是最优的,但这是一个有趣的实验。 在下面,您可以查看代码的实际运行情况以及它的工作原理的解释。
算法
这个想法很简单。 首先,我们为要在 ASCII 艺术中使用的每个字符创建一个图像并将其缓存。 然后,我们遍历原始图像,并为每个字符大小的块,搜索最佳匹配项。 我们首先对原始图像进行一些预处理来实现这一点:我们将图像转换为灰度并应用阈值滤波器。 通过这样做,我们获得一个只有黑白且对比度高的图像,我们可以将其与每个字符进行比较并计算差异。 然后,我们只需选择最相似的字符,直到整个图像都转换完成。 可以根据需要试验阈值以影响对比度并增强最终结果。
实现此目的的一个非常简单的方法是将红色、绿色和蓝色值设置为所有三个值的平均值
RED = GREEN = BLUE = (RED + GREEN + BLUE) / 3。
如果该值低于阈值,则将其设为白色,否则将其设为黑色。 最后,我们逐像素将该图像与每个字符进行比较并计算平均误差。 这在下面的图像和代码片段中演示
int r1 = (charPixel >> 16) & 0xFF;
int g1 = (charPixel >> 8) & 0xFF;
int b1 = charPixel & 0xFF;
int r2 = (sourcePixel >> 16) & 0xFF;
int g2 = (sourcePixel >> 8) & 0xFF;
int b2 = sourcePixel & 0xFF;
int thresholded = (r2 + g2 + b2) / 3 < THRESHOLD ? 0 : 255;
error = Math.sqrt((r1 - thresholded) * (r1 - thresholded) +
(g1 - thresholded) * (g1 - thresholded) + (b1 - thresholded) * (b1 - thresholded));
由于颜色存储在一个整数中,我们首先提取各个颜色分量并执行我解释过的计算。 另一个挑战是准确测量字符尺寸并将其居中绘制。 在尝试了许多不同的方法后,我最终发现这个方法足够好
Rectangle rect = new TextLayout(Character.toString((char) i), fm.getFont(),
fm.getFontRenderContext()).getOutline(null).getBounds();
g.drawString(character, 0, (int) (rect.getHeight() - rect.getMaxY()));
您可以从 GitHub 仓库 下载完整的源代码。
这里有一些使用不同字体大小和阈值的示例
历史
- 2015 年 2 月 15 日:初始版本