首页 > 解决方案 > 如何使用 ASCII 符号绘制图像?

问题描述

我正在尝试从图像中制作 ASCII 艺术,但由于某种原因,输出总是旋转,我多次检查我的代码,但我根本找不到错误。我猜这与它有关imageWidthimageHeight但对我来说一切都很好。

代码可以在github上找到

标签: javaascii-art

解决方案


从图像中绘制 ASCII 艺术作品

让我们假设一个字符占据一个21×8像素区域。所以首先你得把原图按比例缩小,得到这个区域的平均颜色,然后得到这个颜色的平均亮度,然后再转换成一个字符。

原图:

原图

ASCII图片:

ASCII图片


此代码从文件中读取图像,将其缩小到高度的 1/21 和宽度的 1/8,计算缩放区域的平均颜色,然后计算每种颜色的平均亮度并选择一个字符相应的密度,然后将这些字符保存到文本文件中。

没有缩放scH=1scW=1,字符数等于原始图像中的像素数。

public static void main(String[] args) throws IOException {
  // assume that one character occupies an area of 21×8 pixels
  char[][] chars = readImage("/tmp/image.jpg", 21, 8);
  writeToFile("/tmp/image.txt", chars);
}

static char[][] readImage(String path, int scH, int scW) throws IOException {
  BufferedImage image = ImageIO.read(new File(path));
  int height = image.getHeight() / scH;
  int width = image.getWidth() / scW;
  char[][] chars = new char[height][width];
  for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
      // scaling image and accumulating colors
      int colorRGB = 0;
      for (int k = 0; k < scH; k++)
        for (int p = 0; p < scW; p++)
          colorRGB += image.getRGB(j * scW + p, i * scH + k);
      // get the average color
      Color color = new Color(colorRGB / (scH * scW));
      // read the R, G, B values of the color and get the average brightness
      int brightness = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
      // get a character depending on the brightness value
      chars[i][j] = getDensity(brightness);
    }
  }
  return chars;
}

static final String DENSITY =
      "@QB#NgWM8RDHdOKq9$6khEPXwmeZaoS2yjufF]}{tx1zv7lciL/\\|?*>r^;:_\"~,'.-`";

static char getDensity(int value) {
  // Since we don't have 255 characters, we have to use percentages
  int charValue = (int) Math.round(DENSITY.length() / 255.0 * value);
  charValue = Math.max(charValue, 0);
  charValue = Math.min(charValue, DENSITY.length() - 1);
  return DENSITY.charAt(charValue);
}

static void writeToFile(String path, char[][] chars) throws IOException {
  FileWriter writer = new FileWriter(path);
  for (char[] row : chars) {
    String str = String.valueOf(row);
    writer.append(str).write("\n");
    System.out.println(str);
  }
  writer.flush();
  writer.close();
}

输出:

***************************************
***************************************
*************o/xiz|{,/1ctx*************
************77L*```````*_1{j***********
**********?i```````````````FZ**********
**********l`````````````````7**********
**********x`````````````````L**********
**********m?i`````````````iz1**********
************]x```````````\x{***********
********?1w]c>```````````La{]}r********
******jSF~```````````````````^xv>******
*****l1,```````````````````````*Sj*****
****7t```````````````````````````v7****
***uL`````````````````````````````t]***

另请参阅:使用 Java 从 ASCII 艺术作品恢复图像将图像转换为 ASCII 艺术作品


推荐阅读