簡體   English   中英

將位圖轉換為 ASCII 藝術

[英]Convert bitmap to 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@@@@@@@@@@:

這可以在 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);
}

原始來源:

從字符串生成ASCII圖片

將圖像轉換為 ASCII 藝術

  • 尺寸。 讓我們假設一個字符的平均高度是其寬度的兩倍,為了保持相同的比例,我們必須縮小原始圖像。 因此,使用等寬字體是有意義的。

  • 顏色。 我們可以根據字符的密度將像素的亮度轉換為字符。 因此,轉換高對比度的灰度或黑白圖像更准確。

原圖:

Coding Horror

縮放后的 ASCII 圖片:

  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();
  }
}

另請參閱:從 ASCII 藝術作品恢復圖像從圖像繪制 ASCII 藝術作品

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM