2016-11-21 19 views
2

これは基本的に画像のグレー値を下のasciiコードに変換するはずのプログラムの一部ですが、 char型を返す[] [] "空白を表示する最初のもの(" return null ")に成功しました。grayValからAscii文字への変換を使用して画像をAsciiコードに変換する

public static char[][] imageToASCII(Image img) 
{ 
    BufferedImage bufImg = convert(img); 
    for(int j=0; j<bufImg.getHeight(); j++) 
    { 
    for(int i=0; i<bufImg.getWidth(); i++) 
    { 

    int values=bufImg.getRGB(i,j); 
    Color oldColor = new Color(values); 
    int red = oldColor.getRed();  // get red value 
    int green = oldColor.getGreen(); // get green value 
    int blue = oldColor.getBlue(); 
    double grayVal = 0.299*red + 0.587*green + 0.114*blue; 
    Color newColor = new Color((int)grayVal, (int)grayVal, (int)grayVal); 


    if(grayVal >= 230) 
    { 
     return null; 
    } 
    else if(grayVal >= 200 && grayVal < 230) 
    { 
     return .; 
    } 
    else if(grayVal >= 180 && grayVal < 200) 
    { 
     return *; 
    } 
    else if(grayVal >= 160 && grayVal < 180) 
    { 
     return :; 
    } 
    else if(grayVal >= 130 && grayVal < 160) 
    { 
     return o; 
    } 
    else if(grayVal >= 100 && grayVal < 130) 
    { 
     return &; 
    } 
    else if(grayVal >= 70 && grayVal < 100) 
    { 
     return 8; 
    } 
    else if(grayVal >=50 && grayVal < 70) 
    { 
     return #; 
    } 
    else 
     return @ 

    } 
    } 



}} 
+0

さて、メソッドの戻り型が 'でありますchar [] [] 'これは文字の2次元配列です。しかし、あなたは 'return:'のようなものを書くことができます。これは正当なJava文ではなく、 'return ':' 'を使ったとしてもcharの2次元配列ではなく、まだ1つのcharです。 – RealSkeptic

+0

文字の2次元配列のリターンの例を教えてもらえますか? – raymondT

答えて

1

まず、 charを返すには、一重引用符で囲む必要があります。 第2に、実際に文字を返すのではなく、文字のマトリックスに設定することです。以下は、あなたのコードを修正したものです:

import java.awt.image.BufferedImage; 
import java.awt.Color; 

public class Test { 
    public static char[][] imageToASCII(BufferedImage img) { 
    int w = img.getWidth(); 
    int h = img.getHeight(); 
    char[][] res = new char[h][w]; 

    for(int j=0; j<h; j++) { 
     for(int i=0; i<w; i++) { 
     int values = img.getRGB(i,j); 
     Color oldColor = new Color(values); 
     int red = oldColor.getRed();  // get red value 
     int green = oldColor.getGreen(); // get green value 
     int blue = oldColor.getBlue(); 
     double grayVal = 0.299*red + 0.587*green + 0.114*blue; 

     if(grayVal >= 230) { 
      res[j][i] = ' '; 
     } else if(grayVal >= 200 && grayVal < 230) { 
      res[j][i] = '.'; 
     } else if(grayVal >= 180 && grayVal < 200) { 
      res[j][i] = '*'; 
     } else if(grayVal >= 160 && grayVal < 180) { 
      res[j][i] = ':'; 
     } else if(grayVal >= 130 && grayVal < 160) { 
      res[j][i] = 'o'; 
     } else if(grayVal >= 100 && grayVal < 130) { 
      res[j][i] = '&'; 
     } else if(grayVal >= 70 && grayVal < 100) { 
      res[j][i] = '8'; 
     } else if(grayVal >=50 && grayVal < 70) { 
      res[j][i] = '#'; 
     } else { 
      res[j][i] = '@'; 
     } 
     } 
    } 
    return res; 
    } 
} 

また、このコードはパフォーマンス面で非常に非効率的です。 W x H> 255の画像では、連続したifを避けるほうがよいでしょう。画像をループするとき、これは初期化時に対応する文字のそれぞれの可能なグレー値をマッピングするアレイを作成することによって行われ、その後、ちょうどそのような配列を間接参照することができる。

import java.awt.image.BufferedImage; 
import java.awt.Color; 

public class Test { 
    private static char[] map; 

    private static void initMap() { 
    map = new char[256]; 
    int[][] ranges = new int[][] { 
     {0, 50}, {50, 70}, {70, 100}, {100, 130}, 
     {130, 160}, {160, 180}, {180, 200}, 
     {200, 230}, {230, 256} 
    }; 
    char[] v = {' ', '#', '8', '&', 'o', ':', '*', '.', ' '}; 
    for(int i=0; i<v.length; i++) { 
     for(int j=ranges[i][0]; j < ranges[i][1]; j++) { 
     map[j] = v[i]; 
     } 
    } 
    } 

    public static char[][] imageToASCII(BufferedImage img) { 
    if (map == null) { 
     initMap(); 
    } 
    int w = img.getWidth(); 
    int h = img.getHeight(); 
    char[][] res = new char[h][w]; 

    for(int j=0; j<h; j++) { 
     for(int i=0; i<w; i++) { 
     int values = img.getRGB(i,j); 
     Color oldColor = new Color(values); 
     int red = oldColor.getRed();  // get red value 
     int green = oldColor.getGreen(); // get green value 
     int blue = oldColor.getBlue(); 
     int grayVal = (int)(0.299*red + 0.587*green + 0.114*blue); 
     if (grayVal > 255) { 
      grayVal = 255; 
     } 
     res[j][i] = map[grayVal]; 
     } 
    } 
    return res; 
    } 
} 
+0

答えていただきありがとうございますが、変換されたASCII画像は元の画像よりはるかに大きくなりました。最初に10x10ブロックに量子化して元の画像に実装する方法はありますか?好ましくは第1のコード(非効率的なコード) – raymondT

0

はここであなたが返すべきかの構造を示すために、クラスだし、どのようにコンソールに表示する:

package stackOverflow; 

public class ImageToGrayscale 
{ 
    public static void main(String[] args) { 
     char[][] image = return2DChars(30, 10); 
     for (int i = 0; i < image.length; i++) { 
      char[] row = image[i]; 
      for (int j = 0; j < row.length; j++) { 
       System.out.print(row[j]); 
      } 
      System.out.println(); 
     } 
    } 

    public static char[][] return2DChars(int width, int height) { 
     char[][] image = new char[height][width]; 
     for (int i = 0; i < height; i++) { 
      for (int j = 0; j < width; j++) { 
       image[i][j] = (Math.random() < 0.5) ? ':' : '#'; 
      } 
     } 
     return image; 
    } 
} 

これは、出力:すべての

#:#:###:::::#:#::#:::##:#::### 
####:#::###:::#:###:##:::#::## 
##:#:##:##:::#:##::#:###:::::: 
:::#:::###:#::########:#::##:# 
:#::#:####:::#::#:::##::#:#::: 
####::####:#:::##:##::::::#### 
::####:##::#:#::::#::#:#:#::#: 
#::###::##:::####:::#:#:##::## 
#:####::::#####:#####::###:### 
::##:#:###:#:::#::####:::##:#: 
関連する問題