# Bild in einer Variable speichern



## smf68 (9. Okt 2006)

Hi,
Ich versuche nun schon seit Stunden, auf alle mögliche Arten und Weisen Bilder zu laden und in einem Array zu speichern, damit ich sie nachher auf den Bildschirm zeichnen kann.
Ein Bild soll aber nicht nur geladen werden, sondern mit einem CropImageFilter auch noch in 12 Teile zerschnitten werden, diese 12 Teile kommen dann ins Array.

Das sieht im Groben so aus:

```
class  Game
{
	Image[] imgloaded, cutted;

	class GameLoop extends Thread
	{
		while(true)
		{
			// Graphics holen: offg

			offg.drawImage(imgloaded[0], 100, 100, frame);					
			offg.drawImage(cutted[2], 200, 200, frame);
		}
	}

	Game()
	{
		// Thread starten
		// loader und cutter erstellen, etc.

		String[] files = {"char1.png"};

		imgloaded = loader.load(files); // Lädt Bilder mit Mediatracker und gibt sie als Array zurück

		cutted = cutter.cut(imgloaded[0]); // Zerschneidet ein Bild in 12 Teile
	}
}
```

Und jetzt das paradoxe: So wie es hier steht, funktioniert das Programm. Wenn ich aber das erste drawImage auskommentiere (was in der fertigen Version ja so sein soll, ich brauche imgloaded nur, um es zu zerschneiden - angezeigt werden soll es nie!), kriege ich einen weissen Bildschirm. 

Weshalb?

Wie kann ich Bilder in einer Variabeln so speichern, dass sie IMMER da sind, wenn immer ich Lust habe, sie zu zeichnen? Ich dachte eigentlich, dass der MediaTracker genau das macht. 
Ich möchte Bilder nicht nur erstellen und sofort zeichnen, sondern auch aufbewahren, an andere Klassen weitergeben, etc..

Was mache ich falsch?

Wäre echt froh, wenn mir jemand dabei helfen könnte... ich bin am Verzweifeln.

Gruss smf68


----------



## Campino (9. Okt 2006)

Es wäre schön mal den Code der cutter.cut() und der loader.load()-methode zu sehen, so ist der Code wenig aussagekräftig, spontan würde ich sagen, dass die cutter.cut nicht geht und das cutted-Array leer ist. Ansonsten malst du generell nur einen deiner zwölf Teile, das ist dir klar?


----------



## SlaterB (9. Okt 2006)

versuchs doch erstmal mit
cutted = new Image[3];
cutted[2] = imgloaded[0];

und der Anzeige von cutted[2] in Originalgröße,
wenn das funktioniert, dann ist wohl etwas mit der cut-Operation im Eimer,
was immer das auch sein soll


----------



## smf68 (10. Okt 2006)

SlaterB hat gesagt.:
			
		

> versuchs doch erstmal mit
> cutted = new Image[3];
> cutted[2] = imgloaded[0];
> 
> ...



Das funktioniert.


Hier also die cut-Funktion


```
public Image[] cut(Image inp)
{
	Image[] result = new Image[12];

	int x = 0;
	int y = 0;

	for(int i=0;i<4;i++)
	{
		for(int j=0;j<3;j++)
		{
			filter = new CropImageFilter(x, y, 24, 32);
			result[i * 3 + j] = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(inp.getSource(), filter));

			x += 24;
		}
		y += 32;
	}

	return result;
}
```


Nun ist mir noch etwas sehr seltsames aufgefallen: Wenn ich beides zeichne wird imgloaded[0] immer gezeichnet, cutted[2] jedoch nur manchmal, manchmal aber auch gar nicht beim abwechselnden Starten und Beenden des Programmes. Also so:


```
offg.drawImage(imgloaded[0], 10, 10, frame);					
offg.drawImage(cutted[2], 10, 200, frame);
```


Tritt der Fehler womöglich schon beim Laden auf?

Hier die load-Funktion:



```
class ImageLoader
{
	private MediaTracker tracker;

	ImageLoader(Component c_parent)
	{
		tracker = new MediaTracker(c_parent);
	}

	public Image[] load(String[] filenames)
	{
		Image[] imgs = new Image[filenames.length];

		for(int i=0;i<filenames.length;i++)
		{
			imgs[i] = Toolkit.getDefaultToolkit().getImage(filenames[i]);
			tracker.addImage(imgs[i], 0);
		}

		try
		{
			while(tracker.statusAll(true) != MediaTracker.COMPLETE)
			{
				LoadingStatus.status = "Loading image files...";
				tracker.waitForAll();
			}
		}
		catch(InterruptedException e)
		{
			System.exit(0);
		}

		return imgs;
	}
```

Danke für die Hilfe!

Gruss smf68


----------



## smf68 (10. Okt 2006)

Hab mich nochmal drangesetzt, das Problem ist zwar noch immer ungelöst, aber elegant umgangen.

Zuerst einmal hatte cut() einen Fehler:


```
public Image[] cut(Image inp)
{
   Image[] result = new Image[12];

   int x = 0;
   int y = 0;

   for(int i=0;i<4;i++)
   {
      for(int j=0;j<3;j++)
      {
         filter = new CropImageFilter(x, y, 24, 32);
         result[i * 3 + j] = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(inp.getSource(), filter));

         x += 24;
      }
      x = 0; // <------- das hatte gefehlt
      y += 32;
   }

   return result;
}
```

Geholfen hat das alleine aber noch nicht, immernoch die gleichen seltsamen Vorkommnisse - einmal gehts, einmal nicht.
Ich habe nun das ganze Programm umgeschrieben, MediaTracker über den Haufen geworfen und ImageIO benutzt. Jedes Bild wird nach dem CropImageFiltern direkt in ein BufferedImage geschrieben, und jetzt funktioniert es.
Ich kann mir zwar immer noch nicht vorstellen, wieso das mit Image nicht lösbar sein soll, aber naja... 

Gruss smf68


----------



## kaie (11. Okt 2006)

Wie so oft auch hier: asynchrones Laden der Bilder! Die Bilder werden in einem separaten Thread geladen. Warte entweder, bis Dein Bild geladen wurde (mit MediaTracker) oder benutze direkt ein synchronisiertes Laden, z.B. mit ImageIO.


----------



## smf68 (12. Okt 2006)

Das tue ich jetzt ja auch. Seltsam ist nur, dass ich auch nach geraumer Zeit nichts angezeigt bekam... 

Was ich auch gelesen habe ist, dass ein Image-Objekt angeblich nur einmal gezeichnet werden kann, irgendwie aber kaum vorstellbar, weil ich sonst ja gar nie etwas angezeigt bekommen hätte (bzw ziemlich kurz bei einer Framerate von 75). Habe auch in der Doku nichts dazu gefunden. 

Immerhin gehts jetzt ja, ich werde einfach in Zukunft die Finger ganz von Image lassen und nur noch BufferedImage benutzen, damit hatte ich jetzt bei all meinen Tests gar keine Probleme.

Gruss smf68


----------



## kaie (12. Okt 2006)

'tschuldigung, hatte Deinen Thread nur kurz überflogen, und sofort hat der Pawlowsche "Mediatracker"-Reflex eingesetzt! Dafür als Entschädigung eine eigene cut-Methode, die hoffentlich besser funktionieren dürfte:


```
public Image[] zerteileBild( String dateiname, int xTeile, int yTeile )
{
    try
    {
        BufferedImage bi = ImageIO.read( new File(dateiname) );
        int w = bi.getWidth(null)/xTeile;
        int h = bi.getWidth(null)/yTeile;
        Image[] erg = new Image[xTeile*yTeile];
        int nr=0;
        for( int y=0; y<yTeile; y++ )
        {
            for( int x=0; x<xTeile; x++ )
            {
                erg[nr] = new BufferedImage( w, h, BufferedImage.TYPE_INT_RGB );
                erg[nr].getGraphics.drawImage( bi, 0, 0, w, h, w*x, h*y, w*(x+1), h*(y+1) );
            }
        }
        return erg;
    } catch( Exception e ) { return null; }
}
```


----------

