Java的ASCII艺术
1. 概述
在本文中,我们将讨论使用 Java 的 2D 图形支持中的概念在 Java 中创建ASCII 字符或String的图形打印。
2. 用 2D 图形绘制字符串
在Graphics2D类的帮助下,可以将String绘制为图像,通过调用*drawString()*方法来实现。
因为Graphics2D是抽象的,我们可以通过扩展它并实现与Graphics类相关的各种方法来创建一个实例。
虽然这是一项乏味的任务,但通常通过在 Java 中创建一个BufferedImage实例并从中检索其底层Graphics实例来完成:
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics graphics = bufferedImage.getGraphics();
2.1.用 ASCII 字符替换图像矩阵索引
绘制String时,Graphics2D类使用简单的类似矩阵的技术,其中划分出设计String的区域被赋予特定值,而其他区域被赋予第零值。
为了能够用所需的 ASCII 字符替换雕刻区域,我们需要将雕刻区域的值检测为单个数据点(例如整数),而不是 RGB 颜色值。
要将图像的 RGB 颜色表示为整数,我们将图像类型设置为整数模式:
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
基本思想是将分配给图像矩阵的非零索引的值替换为所需的艺术特征。
而表示零值的矩阵的索引将被分配一个空格字符。整数模式的零等效值为 -16777216。
3. ASCII 艺术生成器
让我们考虑一个需要制作“BLOGDEMO”字符串的ASCII艺术的情况。
我们首先创建一个具有所需宽度/高度的空图像,并将图像类型设置为整数模式,如 2.1 节所述。
为了能够在 Java 中使用 2D 图形的高级渲染选项,我们将Graphics对象转换为Graphics2D实例。然后,我们在使用*“BLOGDEMO”字符串调用drawString()*方法之前设置所需的渲染参数:
Graphics2D graphics2D = (Graphics2D) graphics;
graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
graphics2D.drawString("BLOGDEMO", 12, 24);
在上面,12 和 24 分别代表图像上应该开始文本打印的点的 x 和 y 坐标。
现在,我们有一个二维图形,其底层矩阵包含两种类型的判别值;非零和零索引。
但为了让我们了解这个概念,我们将遍历二维数组(或矩阵)并将所有值替换为 ASCII 字符“*”:
for (int y = 0; y < settings.height; y++) {
StringBuilder stringBuilder = new StringBuilder();
for (int x = 0; x < settings.width; x++) {
stringBuilder.append("*");
}
if (stringBuilder.toString().trim().isEmpty()) {
continue;
}
System.out.println(stringBuilder);
}
上面的输出只显示了一个星号 (*) 块,如下所示:
如果我们通过仅将等于 -16777216 的整数值替换为“*”并将其余的整数值替换为“”来区分替换为“*”:
for (int y = 0; y < settings.height; y++) {
StringBuilder stringBuilder = new StringBuilder();
for (int x = 0; x < settings.width; x++) {
stringBuilder.append(image.getRGB(x, y) == -16777216 ? "*" : " ");
}
if (stringBuilder.toString().trim().isEmpty()) {
continue;
}
System.out.println(stringBuilder);
}
我们获得了一个不同的 ASCII 艺术,它对应于我们的字符串“BLOGDEMO”,但在一个像这样的倒置雕刻中:
最后,我们通过将等于 -16777216 的整数值替换为“ ”并将其余的值替换为“*”来反转判别:
for (int y = 0; y < settings.height; y++) {
StringBuilder stringBuilder = new StringBuilder();
for (int x = 0; x < settings.width; x++) {
stringBuilder.append(image.getRGB(x, y) == -16777216 ? " " : "*");
}
if (stringBuilder.toString().trim().isEmpty()) {
continue;
}
System.out.println(stringBuilder);
}
这为我们提供了所需String的 ASCII 艺术: