Skalierung von Bildern zum Start des Programms

xyss

Aktives Mitglied
Guten Morgen java-forum Community.

Ich bin gerade dabei, ein kleines Spiel zu programmieren. Zu einem Spiel gehören natürlich immer Grafiken, welche geladen werden. Das gestaltet sich eigentlich als ziemlich einfach, da ich direkt am Anfang die Grafiken laden lasse, so dass zur Laufzeit keine Grafiken mehr geladen werden müssen. Mein Problem liegt nun beim Skalieren der Bilder.

Das Skalieren benötige ich für folgende Fälle:
In einem YAML-Dokument kann man für jedes "Item" im Spiel gewisse Properties sowie auch Höhe/Breite festlegen, und eine Datei angeben, welche die Textur beinhaltet. Falls diese Bild-Datei eine andere Höhe/Breite als die angegebene hat, wird das Bild auf diese Werte skaliert.
Zudem läuft das Spiel im Fullscreen, das heißt, die Hintergrundgrafik muss ebenfalls skaliert werden.

Das Ganze läuft aktuell über

[Java]
img = new ImageIcon(getClass().getResource("gfx/bg1.png")).getImage().getScaledInstance(width, height, Image.SCALE_FAST);
...
...
...
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(img, 0, 0, null);
[/Java]

Mein Problem ist nun, dass für eine kurze Zeit das Bild erst einmal weiß ist, und nach mehreren repaint()-Aufrufen das Bild erst erscheint (da getScaledImage asynchron läuft, sofern ich das richtig verstanden habe).

Nun würde ich gerne wissen, ob ich irgendwie überprüfen kann, wann getScaledImage fertig ist, also wann das Bild fertig skaliert ist, denn es wäre ja am praktischsten, den Frame erst dann auf visible zu setzen, wenn die Grafiken alle fertig geladen sind.
 
Hallo xyss,

das Verhalten ist ja echt nicht so toll.
Vor allem was die Doku dazu sagt ist ziemlich dürftig; ich kann es nicht so richtig deuten:
The new Image object may be loaded asynchronously even if the original source image has already been loaded completely.

Mein Alternativvorschlag wäre das Skalieren in ungefähr der Gestalt:
Java:
final BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
final Graphics2D g = img.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.drawImage(imageToScale, width, height, null);
 
Alles klar, ich werde dann demnächst deinen Vorschlag ausprobieren (fahre demnächst erstmal in Urlaub), ich werde mein Ergebnis dann posten!

Ein kleines Anhängsel zu dem gleichen Thema:

Ich hatte rein interessehalber das hier versucht:

[Java]
img = new ImageIcon(getClass().getResource("gfx/bg1.png")).getImage().getScaledInstance(width, height, Image.SCALE_FAST);
while ((img.getWidth(null) != width) && (img.getHeight(null)) != height){
}
...
...
...
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(img, 0, 0, null);
[/Java]

Mein Idee war halt, dass das Programm in dieser while-Schleife hängt, bis das Bild fertig skaliert wurde.. hat auch soweit funktioniert (jedenfalls resultierte es nicht in einer Endlosschleife, und die Breite / Länge von img waren direkt nach der while-Schleife auch korrekt. Allerdings wurde das Bild trotzdem erst nach mehreren repaint Aufrufen gezeichnet, obwohl diese while-Schleife vor den repaint-Aufrufen war... das verstehe ich nicht so wirklich. Mehr Code kann ich leider nicht dranhängen, da es wie gesagt nur zum Testen war, als "unelegante Übergangslösung", aber direkt wieder verworfen wurde.

lg
 
Ich habe deinen Codeschnipsel nun eingebaut, jedoch wird das Bild nun gar nicht mehr gezeichnet, sondern einfach gar nichts mehr.
Die Variable background ist das, was du bei dir als imageToScale bezeichnet hast.

Java:
	public void paint(Graphics g){
		Graphics2D g2d = (Graphics2D) g;
		g2d.drawImage(background, 0, 0, null);
	}
 

Zurück
Oben