【问题标题】:Convert bitmap to ASCII art将位图转换为 ASCII 艺术
【发布时间】:2015-10-10 18:26:54
【问题描述】:

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

我想将位图转换为 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@@@@@@@@@@:

【问题讨论】:

    标签: java algorithm image-processing bitmap ascii-art


    【解决方案1】:

    这可以在 Java 中轻松完成,

    int width = 100;
    int height = 30;
    
    //BufferedImage image = ImageIO.read(new File("/logo.jpg"));
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics g = image.getGraphics();
    g.setFont(new Font("SansSerif", Font.BOLD, 24));
    
    Graphics2D graphics = (Graphics2D) g;
    graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
            RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    graphics.drawString("JAVA", 10, 20);
    
    //save this image
    //ImageIO.write(image, "png", new File("/ascii-art.png"));
    
    for (int y = 0; y < height; y++) {
        StringBuilder sb = new StringBuilder();
        for (int x = 0; x < width; x++) {
            sb.append(image.getRGB(x, y) == -16777216 ? " " : "$");
        }
        if (sb.toString().trim().isEmpty()) {
            continue;
        }
        System.out.println(sb);
    }
    

    原文出处:

    Generate an ASCII picture from a string

    【讨论】:

      【解决方案2】:

      将图像转换为 ASCII 艺术作品

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

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

      原图:

      按比例缩放的 ASCII 图片:

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-04
        • 2021-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多