BufferedImage nach dem Speichern immer schwarz

A.T.

Bekanntes Mitglied
Hallo zusammen,

ich lade von openstreetmap die Karten Tiles. Das funktioniert auch prima. Um nicht bei jedem Zoomwechsel oder beim verschieben der Karte alle Tiles neu laden zu müssen, wollte ich die Tiles cachen. Leider bekomme ich es nicht hin die Tiles zu speichern, bzw. die Bilder sind entweder immer alle schwwarz oder alle komplett transparent.
Meine Vermutung ist, das ich beim Umwandeln des Images in ein BufferedImage den falschen Typ auswähle. Aber igendwie scheint da gar nichts zu funktionieren.

Habe ein Testbeispiel gebaut mit dem man das Problem nachstellen kann:
Code:
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;

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

public class BufferedImageTest extends JFrame {

	public BufferedImageTest() {
		super("");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ;
		setLayout(new BorderLayout());
		Panel pan = new Panel();
		pan.setLayout(new BorderLayout());
		add(BorderLayout.CENTER, pan);
		setSize(500, 500);
		setVisible(true);
		pan.setVisible(true);
	}

	public static void main(String[] args) {
		new BufferedImageTest();
	}

	private class Panel extends JPanel {
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
//			loadAndPaintComponent(g);
			loadSaveAndPaintComponent(g);
		}

		// Bild wird bei jedem paint neu geladen und angezeigt <--- Das funktioniert
		private void loadAndPaintComponent(Graphics g) {
			URL url = null;
			try {
				url = new URL("http://tile.openstreetmap.org/" + 16 + "/"
						+ 34320 + "/" + 21924 + ".png");
			} catch (Exception e) {
				e.printStackTrace();
			}
			g.drawImage(Toolkit.getDefaultToolkit().getImage(url), 0, 0, this);
		}

		// Bild nur einmal laden und speichern. Dann immer die Gespeicherte    <----- Diese Version funktioniert nicht!
		// Version verwenden.
		private void loadSaveAndPaintComponent(Graphics g) {
			String tmpPath = System.getProperty("java.io.tmpdir");
			String tmpSavePath = tmpPath + File.separator + "tmpSaveDir";
			File tmpSaveDir = new File(tmpSavePath);
			if (tmpSaveDir.exists()) {
				// Hier wird das schwarze Bild angezeigt. Das Bild im temp Ordner ist bereits schwarz. Laden scheint also zu funktioneren.
				g.drawImage(Toolkit.getDefaultToolkit().getImage(tmpSavePath+ File.separator + "tile.png"),0,0,this);
			} else {
				tmpSaveDir.mkdir();
				URL url = null;
				try {
					url = new URL("http://tile.openstreetmap.org/" + 16 + "/"
							+ 34320 + "/" + 21924 + ".png");
				} catch (Exception e) {
					e.printStackTrace();
				}

				Image image = Toolkit.getDefaultToolkit().getImage(url);

				BufferedImage bufferedImage = new BufferedImage(256, 256,
						BufferedImage.TYPE_3BYTE_BGR); //<------------------------------- hier schient das Problem zu liegen?!
				Graphics bIG = bufferedImage.createGraphics();

				bIG.drawImage(image, 0, 0, null);
				bIG.dispose();
				try {
					ImageIO.write(bufferedImage, "png", new File(tmpSaveDir + File.separator + "tile.png"));
				} catch (Exception e) {
					e.printStackTrace();
				}

				g.drawImage(image,0,0,this);
			}

		}

	}

}
Wäre super wenn mir einer sagen könnte welchen Type ich verwenden muss, bzw. wie ich die Tiles(PNG-Bilder) anders gespeichert bekomme.
Danke!
Gruß
A.T.
 

A.T.

Bekanntes Mitglied
Diese Methode habe ich im i-Net gefunden. Hier gibts die z.B. Image to BufferedImage - Java - Source Code | DreamInCode.net obwohl ich den glaueb ich von einer anderen HP hatte.

Auf jeden fall ist das ja ziemlich aufwändig wenn ich das für jedes Bild durchführen muss. Kann man nicht irgendwie feststellen, welcher Typ es sein müsste und diesen dann einfach verwenden?
Wenn man auf bimage getType() aufruft erhält man eine 1 die einem nicht wirklich weiter hilft...

Code:
	public static BufferedImage toBufferedImage(Image image) {
	    if (image instanceof BufferedImage) {
	        return (BufferedImage)image;
	    }

	    // This code ensures that all the pixels in the image are loaded
	    image = new ImageIcon(image).getImage();

	    // Determine if the image has transparent pixels; for this method's
	    // implementation, see Determining If an Image Has Transparent Pixels
	    boolean hasAlpha = hasAlpha(image);

	    // Create a buffered image with a format that's compatible with the screen
	    BufferedImage bimage = null;
	    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
	    try {
	        // Determine the type of transparency of the new buffered image
	        int transparency = Transparency.OPAQUE;
	        if (hasAlpha) {
	            transparency = Transparency.BITMASK;
	        }

	        // Create the buffered image
	        GraphicsDevice gs = ge.getDefaultScreenDevice();
	        GraphicsConfiguration gc = gs.getDefaultConfiguration();
	        bimage = gc.createCompatibleImage(
	            image.getWidth(null), image.getHeight(null), transparency);
	    } catch (HeadlessException e) {
	        // The system does not have a screen
	    }

	    if (bimage == null) {
	        // Create a buffered image using the default color model
	        int type = BufferedImage.TYPE_INT_RGB;
	        if (hasAlpha) {
	            type = BufferedImage.TYPE_INT_ARGB;
	        }
	        bimage = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
	    }

	    // Copy image to buffered image
	    Graphics g = bimage.createGraphics();

	    // Paint the image onto the buffered image
	    g.drawImage(image, 0, 0, null);
	    g.dispose();

	    return bimage;
	}
 

Michael...

Top Contributor
1. Bist Du Dir sicher, dass das Bild überhaupt gelesen werden kann? Eventuell nutzt Dein Rechner ja einen Proxy um ins Internet zu gehen.
==> mit einer lokalen Datei ausprobieren
2. Selbst wenn das Bild gelesen werden kann. Bist Du Dir sicher, dass das Bild bereits vollständig geladen ist wenn Du es rausschreibst? Toolkit.getImage() wartet nämlich nicht, bis das Bild im Speicher ist.
==> zum Einlesen der Bilder einen MediaTracker oder ImageIO.read() oder ImageIcon nutzen

Als Schnelltest einfach mal die Höhe oder Breite des eingelesenen Bildes ausgeben lassen, vermutlich steht dann bei Dir -1
 

A.T.

Bekanntes Mitglied
Frage 1 kann ich definitiv mit ja beanworten. Frage 2 muss ich wohl eher mit nein beantworten. Habe den "Schnelltest" durchgeführt und der war negativ. Also -1...

Wenn ich ImageIO.read(...) verwende wird das alles ziemlich langsam. Da auf jedes einzelne Bild gewartet wird. Und es sind immer mindestens 25 Tiles eher mehr. Den MediaTracker muss ich mir mal angucken. Habe ich noch nie genutzt. Wäre halt praktisch wenn ich die Bilder sofort al Image anzeigen könnte und später speichern.
 

Michael...

Top Contributor
Wenn ich ImageIO.read(...) verwende wird das alles ziemlich langsam. Da auf jedes einzelne Bild gewartet wird. Und es sind immer mindestens 25 Tiles eher mehr.
Keine Ahnung wie ImageIO Bilder einliest und ob das die schnellste Methode ist, aber man kann Bilder erst anschauen oder abspeichern, wenn sie in den Arbeitsspeicher geladen wurden - und das kann manchmal dauern.
 

Wildcard

Top Contributor
Wenn ich ImageIO.read(...) verwende wird das alles ziemlich langsam. Da auf jedes einzelne Bild gewartet wird. Und es sind immer mindestens 25 Tiles eher mehr. Den MediaTracker muss ich mir mal angucken. Habe ich noch nie genutzt. Wäre halt praktisch wenn ich die Bilder sofort al Image anzeigen könnte und später speichern.
Logik um Bilder aus dem Internet zu Laden, oder noch schlimmer, zu Speichern, hat in einer paintComponent auch nichts verloren.
Lade die Bilder asynchron und zeigst so lange zB Platzhalter.
 

A.T.

Bekanntes Mitglied
@Wildcard bei dem Thema komme ich leider nicht weit. Gibts ein gutes Beispiel für das Thema oder ein Tutorial, wir fehlern irgendwie die richtigen Stichwörter...
 

Landei

Top Contributor
Wenn ich ImageIO.read(...) verwende wird das alles ziemlich langsam. Da auf jedes einzelne Bild gewartet wird. Und es sind immer mindestens 25 Tiles eher mehr.

Threadpool anlegen, Queue mit den Adressen der zu ladenden Bildern erstellen, und die einzelnen Threads das Laden übernehmen lassen. Wenn das funktioniert, Thread-Anzahl optimieren (nicht zu hoch, ich würde mal im Bereich 5 bis 10 versuchen).
 

Ulathar

Aktives Mitglied
@Wildcard bei dem Thema komme ich leider nicht weit. Gibts ein gutes Beispiel für das Thema oder ein Tutorial, wir fehlern irgendwie die richtigen Stichwörter...

Lagere das Laden der Tiles in einen zusätzlichen Worker aus (Thread der im Hintergrund deiner App läuft).
Für jedes Tile dass du anforderst kannst du im GUI ja so lange einen Platzhalter anzeigen (z.b. ein Image, dass Lokal vorliegt). Wenn der Thread dann einen Tile fertig geladen (und gecached) hat, kannst du einfach das geladene Bild den vorher gesetzten Platzhalter ersetzen lassen.

Das Updaten der GUI mit geladenen Tiles köntnest du dann z.B. via Observer/Observables oder so realisieren, so dass immer wenn ein Tile "fertig" ist, ein Update gefeuert wird.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Arbeitsspeicherverbrauch BufferedImage.TYPE_INT_RGB vs. TYPE_3BYTE_BGR AWT, Swing, JavaFX & SWT 6
H BufferedImage zurücksetzen funktioniert nicht AWT, Swing, JavaFX & SWT 12
L AWT Ändern der Farbe eines BufferedImage mit Farbähnlichkeit AWT, Swing, JavaFX & SWT 5
I GEmaltes BufferedImage löschen AWT, Swing, JavaFX & SWT 3
cool_brivk24 BufferedImage einem ClickEvent hinzufügen AWT, Swing, JavaFX & SWT 13
cool_brivk24 AWT BufferedImage wird nicht geladen AWT, Swing, JavaFX & SWT 17
J linken Bildausschnitt eines BufferedImage abschneiden AWT, Swing, JavaFX & SWT 4
Zar von Domarus JFrame zu BufferedImage konvertieren AWT, Swing, JavaFX & SWT 3
S 2D-Grafik User-BufferedImage rotieren im Zentrum und ohne "anpassung" AWT, Swing, JavaFX & SWT 2
C Pixel-Rendering/Animation Performance in BufferedImage AWT, Swing, JavaFX & SWT 1
H Swing BufferedImage zeichnen AWT, Swing, JavaFX & SWT 1
C Swing BufferedImage zeichnen und JLabels setzen. AWT, Swing, JavaFX & SWT 17
G Subimage von BufferedImage speichern AWT, Swing, JavaFX & SWT 4
D JPanel Graphic2D als BufferedImage Speichern AWT, Swing, JavaFX & SWT 5
D BufferedImage -> Feature Extraktion. Unterschiedliche BufferedImage imageTypes problem AWT, Swing, JavaFX & SWT 4
I 2D-Grafik Shape aus BufferedImage "löschen" AWT, Swing, JavaFX & SWT 2
M 2D-Grafik LookupOp Operation auf BufferedImage AWT, Swing, JavaFX & SWT 7
GianaSisters 2D-Grafik BufferedImage.getSubimage - Frage AWT, Swing, JavaFX & SWT 7
P BufferedImage schlechte Qualität beim Abspeichern AWT, Swing, JavaFX & SWT 9
S BufferedImage als schwarz-weiß-Bild AWT, Swing, JavaFX & SWT 3
Luk10 BufferedImage[...].getData() vs BufferedImage.setRGB() AWT, Swing, JavaFX & SWT 2
D Schnelles kopieren von Pixeln in ein BufferedImage AWT, Swing, JavaFX & SWT 25
J Flackern wie mit BufferedImage beheben AWT, Swing, JavaFX & SWT 4
N Swing BufferedImage neu laden AWT, Swing, JavaFX & SWT 10
N 2D-Grafik BufferedImage, Line2D, Swing und die Probleme AWT, Swing, JavaFX & SWT 5
Luk10 BufferedImage auf ein anderes BufferedImage zeichnen AWT, Swing, JavaFX & SWT 6
P BufferedImage auf JPanel AWT, Swing, JavaFX & SWT 11
K 2D-Grafik BufferedImage eingelesen, welches Modell?! AWT, Swing, JavaFX & SWT 2
T BufferedImage bei paintComponent AWT, Swing, JavaFX & SWT 6
C 2D-Grafik BufferedImage laden, Frage zum Code AWT, Swing, JavaFX & SWT 2
0x7F800000 2D-Grafik int[] zu BufferedImage konvertieren AWT, Swing, JavaFX & SWT 27
H 2D-Grafik BufferedImage aus Integer-Array AWT, Swing, JavaFX & SWT 3
Luk10 2D-Grafik BufferedImage sauber rotieren AWT, Swing, JavaFX & SWT 16
P Image mehrfach in ein BufferedImage zeichnen AWT, Swing, JavaFX & SWT 7
J Bild aus Datei in BufferedImage laden AWT, Swing, JavaFX & SWT 4
E BufferedImage Alphaknal ein- und ausblenden AWT, Swing, JavaFX & SWT 7
N BufferedImage zeichnen AWT, Swing, JavaFX & SWT 4
D BufferedImage Größe skalieren AWT, Swing, JavaFX & SWT 2
P Swing Vom BufferedImage bei paintComponent nur soviel zeichnen, wie nötig AWT, Swing, JavaFX & SWT 3
B 2D-Grafik BufferedImage Performance AWT, Swing, JavaFX & SWT 3
Y frage zu BufferedImage AWT, Swing, JavaFX & SWT 7
E AWT RenderedImage aus BufferedImage erzeugen, um Bild abzuspeichern? AWT, Swing, JavaFX & SWT 4
S Unterscheiden ob ein Graphics-Objekt von einer JComponent oder einem BufferedImage kommt..? AWT, Swing, JavaFX & SWT 4
A 2D-Grafik BufferedImage wird nicht eingezeichnet AWT, Swing, JavaFX & SWT 3
G 2D-Grafik BufferedImage Hintergrund immer schwarz AWT, Swing, JavaFX & SWT 4
Developer_X Swing Auf ein BufferedImage mit Graphics/Graphics2D zeichnen AWT, Swing, JavaFX & SWT 6
J AWT BufferedImage to 2DArray AWT, Swing, JavaFX & SWT 10
R Bild drehen UND skalieren (Image bzw BufferedImage) AWT, Swing, JavaFX & SWT 5
J JPanel in Bufferedimage AWT, Swing, JavaFX & SWT 3
1 BufferedImage in byte[], dann in String und zurück AWT, Swing, JavaFX & SWT 7
J Swing paintComponent() - repaint() - BufferedImage anzeigen AWT, Swing, JavaFX & SWT 5
C BufferedImage-Fehler? Falsches Bild wir gezeichnet AWT, Swing, JavaFX & SWT 5
B BufferedImage Builder AWT, Swing, JavaFX & SWT 15
F Transparentes BufferedImage über BufferedImage AWT, Swing, JavaFX & SWT 12
F Größe von BufferedImage ändern AWT, Swing, JavaFX & SWT 27
I Swing JComponent als BufferedImage speichern AWT, Swing, JavaFX & SWT 18
Dragonfire Swing Zoom-Vorgang optimieren [BufferedImage] AWT, Swing, JavaFX & SWT 2
2 Memory Leak mit BufferedImage !! AWT, Swing, JavaFX & SWT 15
X BufferedImage maximiert in JFrame anzeigen? AWT, Swing, JavaFX & SWT 2
R JPanel - BufferedImage - zeichnen großer Bilder AWT, Swing, JavaFX & SWT 2
R JTable - TableCellRenderer - BufferedImage AWT, Swing, JavaFX & SWT 9
D BufferedImage und Graphics2D AWT, Swing, JavaFX & SWT 3
R Zeichnen von Zahlen in BufferedImage AWT, Swing, JavaFX & SWT 6
G BufferedImage.getRGB() mit 3 int-Werten vergleichen AWT, Swing, JavaFX & SWT 2
Luma BufferedImage wird nicht gezeichnet AWT, Swing, JavaFX & SWT 3
G keine ScaledInstance von BufferedImage? AWT, Swing, JavaFX & SWT 6
S BufferedImage & Scaling: Altes Problem im neuen Gewand AWT, Swing, JavaFX & SWT 2
G zu viele/große BufferedImage führt zu Java heap space AWT, Swing, JavaFX & SWT 5
G BufferedImage und jpg --> maximale Qualität AWT, Swing, JavaFX & SWT 9
F HTML Text irgendwie auf BufferedImage bringen AWT, Swing, JavaFX & SWT 3
R BufferedImage Problem AWT, Swing, JavaFX & SWT 2
G Problem mit BufferedImage und imageIO AWT, Swing, JavaFX & SWT 2
S BufferedImage drehen AWT, Swing, JavaFX & SWT 3
? ActionListener auf BufferedImage AWT, Swing, JavaFX & SWT 11
M BufferedImage mit html interpretierten String beschriften AWT, Swing, JavaFX & SWT 3
A Probelme mit großen BufferedImage in paintComponent AWT, Swing, JavaFX & SWT 7
B Farbtiefe eines BufferedImage verringern AWT, Swing, JavaFX & SWT 3
F ImageIcon -> BufferedImage AWT, Swing, JavaFX & SWT 2
T Performance Problem bei BufferedImage AWT, Swing, JavaFX & SWT 3
F Animiertes Gif als BufferedImage AWT, Swing, JavaFX & SWT 10
L Anzeigen von fotos: ImageIcon oder BufferedImage + paint() ? AWT, Swing, JavaFX & SWT 5
C Rotate BufferedImage --> Bild unvollständig AWT, Swing, JavaFX & SWT 5
U Streifen hinter bewegtem BufferedImage AWT, Swing, JavaFX & SWT 13
M BufferedImage skalieren AWT, Swing, JavaFX & SWT 6
T BufferedImage verkleinern Resultat ist zu pixelig. AWT, Swing, JavaFX & SWT 6
G Image Object speichern oder in ein BufferedImage umwandeln AWT, Swing, JavaFX & SWT 2
P Problem beim Zeichnen auf ein BufferedImage AWT, Swing, JavaFX & SWT 4
B BufferedImage aus einer Datei AWT, Swing, JavaFX & SWT 4
C Farben in BufferedImage ändern ? AWT, Swing, JavaFX & SWT 2
J Image to BufferedImage AWT, Swing, JavaFX & SWT 5
T BufferedImage kopieren AWT, Swing, JavaFX & SWT 3
T BufferedImage Farbe "Transparent" AWT, Swing, JavaFX & SWT 21
T BufferedImage + bestimmten bereich ausfüllen AWT, Swing, JavaFX & SWT 3
M BufferedImage Größe? AWT, Swing, JavaFX & SWT 10
U Löschen eines BufferedImage AWT, Swing, JavaFX & SWT 7
J Image aus BufferedImage ohne AWT AWT, Swing, JavaFX & SWT 5
V Image in BufferedImage AWT, Swing, JavaFX & SWT 3
J BufferedImage aus byte-Array erstellen AWT, Swing, JavaFX & SWT 3
berserkerdq2 Buttons und Shapes sehen ja nach Screengröße klein oder zu groß aus, jemand eine Idee, was man tun kann? AWT, Swing, JavaFX & SWT 1
W JEditorPane textausrichtung nach settext funktioniert nicht mehr AWT, Swing, JavaFX & SWT 11

Ähnliche Java Themen

Neue Themen


Oben