java - 将位图转换为 ASCII 艺术

标签 java algorithm image-processing bitmap ascii-art

这样的图像转换算法是如何工作的?

我想将位图转换为 ASCII 艺术。谁能帮我看看我应该使用哪种算法?

                 .   W    ,                
                 W   W    @                
                 W  ,W    W                
              ,  W, :W*  .W  .             
              #  WW @WW  WW  #             
              W  WW.WWW  WW: W             
              W. WW*WWW# WW@ W             
           * :WW.WWWWWWW@WWW@W  #          
          +* #WW#WWWWWWWWWWWWW# W          
          W# @WWWWWWWWWWWWWWWWW W          
          WW WWWWWWWWWWWWWWWWWW W          
          WW WWWWWWWWWWWWWWWWWW@W#         
         ,WW.WWWWWWWWWWWWWWWWWWWWW         
          WW@WWWWWWWWWWWWWWWWWWWWW         
        : WWWWWWWWWWWWWWWWWWWWWWWW :       
        @ WWWWWWWW@WWWWWWW@@WWWWWW.        
        W*WWWWWW::::@WWW:::::#WWWWW        
        WWWWWW@::   :+*:.   ::@WWWW        
        WWWWW@:*:.::     .,.:.:WWWW        
        @WWWW#:.:::.     .:: #:@WWW        
        :WWW@:#. ::     :WWWW:@WWWW        
         WWW#*:W@*@W     .   W:#WWW        
        #WWWW:@      ::   ::  *WWWW        
        W@WW*W  .::,.::::,:+  @@WW#,       
        WWWW## ,,.: .:::.: .  .WWW:,       
        @WWW@:   W..::::: #.  :WWWW        
         WWWW::  *..:.  ::.,. :WWWW        
         WWWW:: :.:.:   :  :: ,@WW@        
         WWWW:  .:,  :  ,,     :WW,        
         .: #         :  ,     : *         
          W +    .,  :::  .,   : @         
          W ::                .: W         
       @,,,W:.  ,, ::*@*:,  . :@W.,,@      
     +.....*: : : .#WWWWW:  : .#:....+,    
    @...:::*:,, : :WWWWWWW, ,  *::::..,#   
  :...::::::W:,   @W::::*W.   :W:::::...#  
 @@@@@@@@@@@W@@@@@W@@@@@@W@@@@@W@@@@@@@@@@:

最佳答案

将图像转换为 ASCII 艺术

  • 大小。假设一个字符的平均高度是其宽度的两倍,为了保持相同的比例,我们必须缩小原始图像。因此,使用等宽字体是有意义的。

  • 颜色。我们可以根据字符的密度将像素的亮度转换为字符。因此,转换高对比度的灰度或黑白图像更准确。

原图:

Coding Horror

缩放后的 ASCII 图片:

<表类="s-表"> <头>
scH=16, scW=8
scH=8, scW=4
scH=2, scW=1
scH=16, scW=8 scH=8, scW=4 scH=2, scW=1
class ImageToASCIIArt {
  public static void main(String[] args) throws IOException {
    char[][] chars = readImage("/tmp/image.jpg", 16, 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();
  }
}

另请参阅:Restore an image from an ASCII artDraw an ASCII art from an image

关于java - 将位图转换为 ASCII 艺术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31536707/

相关文章:

ruby - 数字范围相减算法

algorithm - 在散列算法之上使用另一种算法

java - GWT 中的 ScrollPanel 内的 DockLayoutPanel

java - Spring Batch 输出记录多于输入记录

java - MiniMax 返回反向效用值

android - 从Android中的图像进行数字检测

c++ - 高斯模糊不均匀

python - 使用opencv和python将图像转换为值(例如十六进制代码)

java - WsImport 找不到导入的证书

java - JUnit 4 : Set up things in a test suite before tests are run (like a test's @BeforeClass method, 仅用于测试套件)