# ASCII Art von Bild erstellen.



## tuipferd (11. Mai 2012)

Hallo...

Ich soll mit Eclipse ein BIld einlesen und dann daraus ein ASCII-Art Bild machen....

so soll das dann danach aussehen:
http://www.codeproject.com/KB/web-image/ASCIIArt/ASCIIArt3.gif

Ich hab nur leider nicht wirklich Ahnung davon...

Danke schonmal für jede Hilfe!


----------



## Gossi (11. Mai 2012)

Was hast du denn schon versucht, welche Ideen hast du, hast du schon Quellcode, fang doch erstmal mit dem einlesen des Bildes an, ohne weiter Infos, kann und wird dir hier wahrscheinlich keiner Helfen.


----------



## Gast2 (11. Mai 2012)

Glaubst du ehrlich irgendjemand macht das aus Spass an der Freude? Sowas ist: 

1) Nicht trivial, also 100% kein Anfänger Thema!
2) Aufwendig 
3) Mit Sicherheit nicht kostenlos zu haben 

==> Bitte in die Jobbörse/Hausaufgabenecke verschieben


----------



## tuipferd (11. Mai 2012)

Also, dass ich das bild einlesen muss und dann wahrscheinlich die Pixel in nem Array speicher und dann die dann irgendwie durch ASCII Zeichen ind er gelichen Farbe ersetze ist mir soweit schon klar...(oder ist das falsch?

aber wie mache ich das?


----------



## Gossi (11. Mai 2012)

Fang doch erstmal an, mit dem einlesen des Bildes und zeichne es in ein Fenster, damit du siehst ob das schonmal funktioniert, dann Postest du den Quellcode den du bis dahin hast hier, zusammen mit deinen Lösungsansätzen fürs Convertieren, dann kann dir vielleicht auch einer Helfen.


----------



## Gast2 (11. Mai 2012)

tuipferd hat gesagt.:


> Also, dass ich das bild einlesen muss und dann wahrscheinlich die Pixel in nem Array speicher und dann die dann irgendwie durch ASCII Zeichen ind er gelichen Farbe ersetze ist mir soweit schon klar...(oder ist das falsch?
> 
> aber wie mache ich das?



Stichworte: 

Bild einlesen + Java
ArrayList + Java 
File +Java

Versuch daraus mal ein Programm zu machen, welches ein Bild öffnet und einliest. Wenn was nicht funktioniert poste deinen Code. Dann wird dir geholfen. 

Es wid hier (hoffentlich) keiner den Code für dich schreiben. Dafür gibts wie bereits erwähnt die Jobbörse.


----------



## vanny (11. Mai 2012)

tuipferd hat gesagt.:


> aber wie mache ich das?



1. Buch nehmen und Basics lernen.
2. - x. Viel üben
x.+1 Programm schreiben

im ernst, poste mal irgendwas, womit man arbeiten kann


----------



## diggaa1984 (11. Mai 2012)

sollst du das komplett selbst machen oder darfst dich einer Library bedienen? Gibts ja einige.


> die Pixel in nem Array speicher und dann die dann irgendwie durch ASCII Zeichen ind er gelichen Farbe ersetze ist mir soweit schon klar...(oder ist das falsch?


dürfte schwierig werden, da deine Pixel größentechnisch nicht nem ASCII-Zeichen gleichzusetzen sind ^^

Raster dein Bild mit fixen Pixelblöcken (1 ASCII-Zeichen pro Pixelblock) .. berechne den durchschnittlichen Grauwert des Pixelblocks und ordne dem Wert nen ASCII-Zeichen zu. Das mal als ganz simpler Ansatz (wenn es nicht bunt sein soll).


----------



## Schwertfisch (11. Mai 2012)

Hey,

ich habe mal so etwas in die Richtung  gemacht. Schau es dir mal an es wird dir glaube ich einen Ansatzpunkt geben... 


```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashSet;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class bot extends JPanel implements Runnable {

	private static final long serialVersionUID = -7895958135615431190L;
	JFrame frame;
	private BufferedImage pic;
	java.net.URL first = getClass().getResource("pic/try2.jpg");

	public static void main(String[] args) {
		new bot(430, 70);
	}

	public bot(int i, int j) {
		this.setPreferredSize(new Dimension(i, j));
		frame = new JFrame("");
		frame.setLayout(new BorderLayout());
		frame.setLocation(100, 100);
		this.setBackground(new Color(195, 195, 195));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(this);
		frame.setVisible(true);
		frame.pack();
		Thread th = new Thread(this);
		th.start();

	}

	@SuppressWarnings("unused")
	public BufferedImage getPixels(BufferedImage image) {
		int bereich = 1;
		int[][] sp = new int[430][70];
		BufferedImage nextimage = new BufferedImage(image.getWidth(),
				image.getHeight(), image.getType());
		Graphics2D g2 = nextimage.createGraphics();
		g2.setColor(Color.white);
		g2.fillRect(0, 0, image.getWidth(), image.getHeight());
		g2.setColor(Color.BLACK);
		for (int x = 0; x < image.getWidth(); x++) {
			for (int y = 0; y < image.getHeight(); y++) {

				int icolor = image.getRGB(x, y);
				Color c = new Color(icolor);
				if (!isLetter(icolor)) {
					sp[x][y] = 0;
				}
				if (isLetter(icolor)) {
					g2.fillRect(x, y, 1, 1);
					pic = nextimage;
					repaint();
					sp[x][y] = 1;
				}
			}
		}
		HashSet<Point> openlist = new HashSet<Point>();
		HashSet<Point> closelist = new HashSet<Point>();
		Point p = new Point();
		for (int j = 0; j < sp[0].length; j++) {
			for (int i = 0; i < sp.length; i++) {
				System.out.print(sp[i][j]);
//				openlist.add();
			}
			
			System.out.println();
		}
		g2.dispose();
		return nextimage;
	}

	private boolean isLetter(int icolor) {
		Color c = new Color(icolor);
		float mittle = (c.getBlue() + c.getRed() + c.getGreen()) / 3f;

		return mittle < 50;

	}

	public void getImage() throws IOException {
		pic = ImageIO.read(first);
	}

	public void paintComponent(Graphics g) {
		g.drawImage(pic, 0, 0, frame);

	}

	@Override
	public void run() {

		try {
			getImage();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		pic = getPixels(pic);
		repaint();
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
		}
	}
}
```

Es geht NUR mit einem Bild dieser art wie ich es im anhang habe...


----------



## turtle (11. Mai 2012)

Dazu gebe ich das Stichwort Figlet und Du solltest Dir mal das hier ansehen.


----------



## Dow Jones (11. Mai 2012)

Also wenn man sich das Beispielbild anschaut - da steckt ja gar nichts hinter... Es wird immer das gleiche Zeichen verwendet, nur die Farbe wird angepasst. 

Hier meine Lösung: Trivial, nicht aufwendig, und kostenlos. 

```
BufferedImage myImage = ImageIO.read( new File(...) );
            double step = myImage.getHeight() / 80.0;
            for( double y=0; y<myImage.getHeight(); y+=step) {
                for( double x=0; x<myImage.getWidth(); x+=step) {
                    // farbe fuer Zeichen an Position x, y
                    int color = myImage.getRGB((int)x, (int)y) & 0xffffff;
                }
            }
```

Resultat:


----------



## tuipferd (11. Mai 2012)

Vielen vielen Dank!

Bei mir klappt es zwar noch nicht wirklich. Aber ich versuchs weiterhin...
Bekomme das mit der Ausgabe noch nicht wirklich hin...


----------



## Dow Jones (11. Mai 2012)

Ich hatte mir das Bild der Einfachheit halber als HTMLcode ausgeben lassen. Jedes Zeichen einzeln in ein <span> mit der jeweiligen Farbe eingepackt. Nicht eben schön, aber es funktioniert - und HTML kann man ja praktischerweise auch gleich in einem JEditorPane oder so anzeigen. 
Woran scheitert es denn gerade bei dir?


----------



## tuipferd (11. Mai 2012)

Ja das Problem ist, dass ich eigentlich noich nie was mit Grafiken in Eclipse gemacht habe...hab mir das ganze APi Zeug dazu schon durchgelesen aber so wirklich blick ich noch nicht da durch...


----------



## Firephoenix (11. Mai 2012)

Dann mal die Grobzusammenfassung anhand von Dow Jones Beispiel:

Du musst das Bild von einer Datei in Java reinkriegen damit du darauf arbeiten kannst.
Dazu brauchst du zuerst mal ein File-Objekt das auf deine Datei zeigt (google).
mit der Zeile hier kannst du das Bild dann einlesen:

```
BufferedImage myImage = ImageIO.read( new File(...) );
```
statt ImageIO.read() bekommt als Parameter dein File-Objekt übergeben, dass auf die Datei mit dem Bild zeigt.

Jetzt hast du ein BufferedImage-Objekt, du musst aus diesem also wohl irgendwie Farbwerte auslesen.


```
int color = myImage.getRGB((int)x, (int)y) & 0xffffff;
```

liefert dir den Farbwert an dem gegebenen Pixel, je nach format das du brauchst (rgb etc) gibt  es noch verschiedene Alternativen:
How to read pixel color in a java BufferedImage with transparency - Stack Overflow
Hier kriegst du z.b. r g b getrennt in einzelne ints.

Als nächstes musst du daraus irgendeinen Text zusammensetzen (z.b. ein Buchstabe pro Pixel - wird für den Anfang am leichtesten sein)
dazu bieten sich z.b. html-tags mit farbe an die du für jeden Pixel generierst (die farben die du ausgelesen hast fügst du dort dann passend ein).
Am Ende hast du dann hoffentlich irgend etwas in richtung von fertig formatiertem html-code den du z.b. in einer JEditorPane ausgeben kannst

Gruß


----------



## tuipferd (22. Mai 2012)

```
public class Bild extends JPanel {

		public void paint(Graphics g) {
		
			 for(int y=0; y<myImage.getHeight(); y++) {
		            for(int x=0; x<myImage.getWidth(); x++) {
		             
		                int color = myImage.getRGB((int)x, (int)y);
		              
		                g.setColor((Color ???);
		                g.drawString ("i", x, y);
		                
	
		            }}
}

		
		
			public static void main(String[] args) throws IOException {
			
				BufferedImage myImage = null;
				myImage = ImageIO.read (new File ("C:......jpg"));
				
				JFrame f = new JFrame();
		    	f.setSize(myImage.getWidth(), myImage.getHeight());
				f.setTitle("ASCII");
				f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				f.setVisible(true);
				
					
}
			
}
```

Das hab ich jetzt...mein Problem icst jetzt aber ja, dass der in der paint mein Bild ja nicht kennt...ausserdem hab ich die Frabe des Pixels ja als int udn wie kann ich das dann dem setcolor zuweisen??

Danke


----------



## Mr.Crow (22. Mai 2012)

Möchte nicht allzu ins Thema rein reden.

Mit dem [c]int color = myImage.getRGB((int)x, (int)y);[/c] kennt ja Paint das eingelesene Bild.jpg ?

Die Farbe bestimmst du selber, oder nicht ?


----------



## HimBromBeere (22. Mai 2012)

> [JAVA=11]g.drawString ("i", x, y);
> [/code]


Vom Prinzip ist das erstmal richtig, aber der Buchstabe "i" ist breiter als 1Px. Also solltest du, wie Dow Jones schonmal sagte, eine Schrittweite angeben, die für dei Breite eines Zeichens steht, damit eben nicht an jedem Pixel ein i geschrieben wird, sondern erst an jedem 30. oder was auch immer...

Wenn deine paint-Methode das Bild nicht kennt, dann deklarier es doch einfach als Instanzvariable, ist doch naheliegend, dass eine Instamz der Klasse Bild auch irgendwie ein solches Bild als Instanzvariable besitzt, oder irre ich mich da?



> ```
> g.setColor((Color ???);
> ```


Auch darüber hat DowJones was geschrieben, was hier im Forum sogar von FirePhoenix widerholt worden ist.


----------



## tuipferd (29. Mai 2012)

Hallo...
Habe noch einmal eine Frage...

Soweit klappt es jetzt habe aber immer noch ein bisschen das Problem mit mrinrm Bild was in meiner paint Methode nicht erkannt wird...

Habe jetzt eine Instanzvariable Bild und erstelle mein neues Bild aber doch immer noch in der main...


```
Bild myImage = new Bild (ImageIO.read (new File ("C:\\...\\...\\....jpg")));
```

ich bekomm es so immer noch nciht hin, dass ich in der PAint darauf zugreifen kann... also auf myImage..

Stehe son bisschen aufm Schlauch...

Danke nochmal!


----------



## HimBromBeere (29. Mai 2012)

Mit der von dir geschriebenen Zeile legst du ja auch eine neue Referenz mit dem Namen MyImage an (sprich du überschreibst die alte), was normalerweise aber hin wie her zu einem Colmpiler-Fehler führen sollte. Schreib stattdessen:

```
public class Bild extends JPanel {
    BufferedImage myImage = null;
    public void paint(Graphics g) {
        // do something with myImage
    }
        
    public static void main(String[] args) throws IOException {
        myImage = ImageIO.read (new File ("C:......jpg"));
        // ...
    }            
}
```


----------



## Crian (29. Mai 2012)

HimBromBeere hat gesagt.:


> Mit der von dir geschriebenen Zeile legst du ja auch eine neue Referenz mit dem Namen MyImage an (sprich du überschreibst die alte), was normalerweise aber hin wie her zu einem Colmpiler-Fehler führen sollte. Schreib stattdessen:
> 
> ```
> public class Bild extends JPanel {
> ...



Das wird so nicht gehen, da myImage nicht statisch ist. vermutlich hast du den Konstruktor und main da vermengt?


----------



## HimBromBeere (29. Mai 2012)

> Das wird so nicht gehen, da myImage nicht statisch ist. vermutlich hast du den Konstruktor und main da vermengt?


Oh, das stimmt natürlich, hast Recht. Da müsste entweder die Variable statisch gemacht werden (also so: 
	
	
	
	





```
static BufferedImage myImage = null;
```
)
oder du müsstest in der main eine neue Instanz der Klasse Bild anlegen und dort (z.B. im Konstruktor) das Bild laden.


----------



## tuipferd (29. Mai 2012)

cool danke...jetzt erkennt er es...er zeichnet mir aber trotzdem noch nichts :/

Das ist jetzt mein paint : 


```
double step = myImage.getHeight() / 80.0;
        for( int y=0; y< myImage.getHeight(); y+=step) {
            for( int x=0; x< myImage.getWidth(); x+=step) {
            	
            	int color = myImage.getRGB(x, y);

            	int  red = (color & 0x00ff0000) >> 16;
            	int  green = (color & 0x0000ff00) >> 8;
            	int  blue = color & 0x000000ff;
            	
            	Color farbePixel = new Color(red, green, blue);
 
                
                	g.setColor (farbePixel);
	                g.drawString ("i", x, y);
```

Was mache ich falsch??
danke


----------



## tuipferd (29. Mai 2012)

ALso ich hab jetzt alles immer weiter umgestellt und probiere immer wieder alles aus....im Moment sieht mein Programm so aus...

[Java]public static void main (String args[]) throws IOException {


		BufferedImage myImage = ImageIO.read (new File ("C:\\.......\rt.jpg"));


		JFrame f = new JFrame();
    	f.setSize(myImage.getWidth(), myImage.getHeight());
		f.setTitle("ASCII");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setVisible(true);


}[/code]


```
public class Bild extends JPanel{

	
	
BufferedImage myImage = null;




	public Bild (BufferedImage myImage){

	this.myImage = myImage;
	
	}

	



	public void paint(Graphics g){
		
		double step = myImage.getHeight() / 80.0;
        for( int y=0; y< myImage.getHeight(); y+=step) {
            for( int x=0; x< myImage.getWidth(); x+=step) {
            	
            	int color = myImage.getRGB(x, y);

            	int  red = (color & 0x00ff0000) >> 16;
            	int  green = (color & 0x0000ff00) >> 8;
            	int  blue = color & 0x000000ff;
            	
            	Color farbePixel = new Color(red, green, blue);
 
                
                	g.setColor (farbePixel);
	                g.drawString ("i", x, y);
            }
            }
        }

	
	
	
	
	public int getWidth() {
		
		int width = myImage.getWidth();
		
		return width;
	}
	
	
	
	
	public int getHeight() {
		
		int height = myImage.getHeight();
		
		return height;
	}
	
	
	
	
	
	public int getRGB (int x, int y) {
		
		int rgb = myImage.getRGB(x, y);
		
		return rgb;
	}

	

	
	
	
	
	
}
```

Ich komm grad echt nicht mehr weiter....die ganzen Methoden brauch ich so glaub ich gra nicht...hatte es eben alles aber mal was anders und da brauchte ich die...
Bitte helft mir  ich bin immer mehr verwirrt und mit jeder neuen Idee die ich habe läuft es weniger...


----------



## SlaterB (29. Mai 2012)

durchatmen und an die Grundregeln des Lebens zurückdenken,
in deinem Posting fehlt jede Frage abgesehen von 'es geht nicht',
ist es nicht sinnvoll, das aktuelle Problem zu benennen?

kompiliert das Programm oder gibt es Fehlermeldungen?
läuft das Programm oder gibt es Exceptions?
wird falsch dargestellt?


----------



## tuipferd (29. Mai 2012)

ja sorry ...

Also es läuft durch ohne eine Fehlermeldung zurückzugeben ....

Es wird aber nichts gezweichnet...es öffnet sich ein Fenster in der größe meines Bildes(das klappt also) das ist aber leer (also grau) also denk ichmal dass irgendwas mit meiner paint methode nicht stimmt...


----------



## tuipferd (29. Mai 2012)

Ja sorry :/

Also es läuft durch ohne ne Fehlermeldung...
Es zeichnet mir aber nichts in mein Feld...das Feld wird in der Richtigen größe erzeugt ist aber dann leer...
Würde ja dafür sprechen, dass irgendwas an der paint methode nicht stimmt...oder??


----------



## SlaterB (29. Mai 2012)

ich dachte zuletzt noch es fehlen Zwischenklassen und hatte vorerst noch nicht nach vielleicht 'all dem großen Gesamtprogramm' gefragt,
jetzt aber sehe ich, dass du in der main-Methode ja nur ein JFrame öffnest,

die Bild-Klasse ist gar nicht beteiligt/ eingebunden?
auf solche Grundlagen wirklich immer achten, den Blick fürs wesentliche schärfen,
es hilft nicht die 20 Drähte in einer Lampe hin und her zu drehen, wenn der Stecker gar nicht in der Steckdose steckt


----------



## tuipferd (29. Mai 2012)

Ah doch sorry...durch das ganze hin und her hab ich die falsche main geschickt...

also in der mein hab ich eigentlich :


```
Bild myImage = new Bild (ImageIO.read (new File ("C:\\........\\rt.jpg")));
```

was an meiner Ausgabe aber nichts ändert...


----------



## SlaterB (29. Mai 2012)

solange myImage nicht ins JFrame aufgenommen wird, kein Wunder

aber wenn du so nichtmal feststellen kannst, ob paint je aufgerufen wird (Ausgabe reinsetzen!)
kann man bei all den noch kommenden tausenden Fehlern ja schwarz sehen, hmm


----------



## tuipferd (29. Mai 2012)

SlaterB...

Du als Moderator kannst doch Beiträge berabeiten...oder? Könntest du vielleicht aus meinem Beitrag 24 und 29 den Pfad rausnehmen...ich bin ja nur Gast und kann das nicht
Danke


----------



## SlaterB (29. Mai 2012)

fertig, Bildname aus zwei Buchstaben hoffenlich nicht schädlich


----------



## tuipferd (29. Mai 2012)

Danke


----------

