Problem beim Erzeugen eines Images aus byte[]

Kai008

Erfahrenes Mitglied
Ich will ein Bild als Hexadezimale Zeichen in eine Datenbank schreiben und von dort mit dem Clienten anzeigen.
Leider funktioniert es nicht. :(
Ich habe es jetzt auf einen kleinen Code gekürzt, der von der HDD ein Bild als bytes ließt, und nach der Umwandlung wieder abspeichert.

Java:
File f = new File("C:\\Dokumente und Einstellungen\\Kai\\Desktop\\planet.png");
byte[] buffer = new byte[(int) f.length()];
			
FileInputStream fileInputStream = new FileInputStream(f);
fileInputStream.read(buffer, 0, buffer.length);

Image img = Toolkit.getDefaultToolkit().createImage(buffer);
BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();
ImageIO.write(image, "png", new File("C:\\planet.png"));

Das Bild ist ca. 5 kb groß, der Output nur 0.4. Erkennt zufällig jemand, was ich da falsch mache?
 
Moin,

nein, so direkt fällt mir an Deinem Code nix auf!

Allerdings lese ich an mehreren Stellen div. Bilder direkt als BufferedImage ein :
Java:
String strImage "...";  // Pfad und Name des Name des Pics
...
BufferedImage myImage = null;
try 
{
    myImage = ImageIO.read( new File(strImage) );
} 
catch (IOException ex) 
{}

Vlt. hilft Dir das ja weiter ...
Gruß
Klaus
 
Wenn ich das richtig verstanden hab, dann war das Beispiel nur fiktiv und eigentlich soll das Bild ja aus der Datenbank gelesen werden, da kann man ImageIO.read() vergessen.

Kai, eigentlich ist das alles soweit ok, einziges Problem ist scheinbar nur, dass du nicht wartest, bis das Bild vollständig erstellt wurde aus den Bytes. Das Bild wird also schon geschrieben noch bevor es überhaupt vollständig ist. Mit MediaTracker kann man das Programm warten lassen, bis das Bild erstellt wurde.
Java:
package de.tutorials.kai008.image;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

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

public class ImageSample {
	public static void main(String[] args) throws IOException,
			InterruptedException {
		File f = new File("/home/link/Bilder/revy.png");
		byte[] buffer = new byte[(int)f.length()];

		FileInputStream fileInputStream = new FileInputStream(f);
		fileInputStream.read(buffer, 0, buffer.length);

		Image img = Toolkit.getDefaultToolkit().createImage(buffer);

		// Warten, bis das Bild vollständig erstellt wurde
		MediaTracker mt = new MediaTracker(new JPanel());
		mt.addImage(img, 0);
		mt.waitForAll();

		BufferedImage image = new BufferedImage(300, 300,
				BufferedImage.TYPE_INT_ARGB);
		Graphics g = image.getGraphics();
		g.drawImage(img, 0, 0, null);
		g.dispose();
		ImageIO.write(image, "png",
				new File("/home/link/Bilder/revy_kopie.png"));
	}
}
Ansonsten war alles in Ordnung und funktioniert 1a.
 
Oh, danke. :)
Mein erster Ansatz war, den Dateiinhalt einfach nur im Source für dem Test zu kopieren, ist bei ca. 5 kb ja nicht so extrem viel.
Das funktioniert leider immer noch nicht.

Java:
String planetHexString = "89504E470D0A1A0A0000000D4...";

byte[] b = new BigInteger(planetHexString, 16).toByteArray();
Image planetImage = Toolkit.getDefaultToolkit().createImage(b);
		
try
{
	MediaTracker tracker = new MediaTracker(new Container());
	tracker.addImage(planetImage, 0);
	tracker.waitForID(0);

	BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
	Graphics g = image.getGraphics();
	g.drawImage(planetImage, 0, 0, null);
	g.dispose();
	ImageIO.write(image, "png", new File("C:\\planet.png"));
}
catch (IOException e)
{
	e.printStackTrace();
}
catch (InterruptedException e)
{
	e.printStackTrace();
}

Der Inhalt ist richtig, habe ihm mit einen Hexeditor in eine leere Datei eingefügt, und der MD5-Fingerprint war 1:1 der Sourcedatei.
 
Hallo,

ich denke, dass das Problem bei dir in Zeile 3 liegt
Java:
byte[] b = new BigInteger(planetHexString, 16).toByteArray();

Laut der Java-API dient der von dir verwendete Konstruktor dazu, genau EINEN BigInteger zu erstellen. Denke aber kaum, dass sich deine Datei durch eine Zahl darstellen lässt.

Gruß
BK
 
Danke. Ich habe das jetzt mit einer Schleife ersetzt, hat aber leider nichts bebracht.

Java:
byte[] b = new byte[planetHexString.length() / 2];
for (int i = 0, size = b.length; i < size; i++)
	b[i] = (byte) Integer.parseInt(planetHexString.substring(i, i + 2), 16);
 
Hallo,

bei der Schleife musst du nicht um 1 Position weiterzählen, sondern um 2, dann sollte das funktionieren ;)

Java:
for (int i = 0, size = b.length; i < size; i+=2)

Gruß
BK
 
Hab auch mal was gemacht zum Umrechnen von Hex-Strings zu bytes.
Java:
package tests.zahlen;

import java.util.Arrays;

public class HexZahlen {
	public static void main(String[] args) {
		// for(int i = 0; i < 10; i++) {
		// int zahl = (int)(Math.random() * 256);
		// System.out.println(zahl + " => " + Integer.toHexString(zahl));
		// }

		// Ergebnis der Schleife:
		// 172 78 26 222 241 114 188 160 82 15
		// AC4E1ADEF172BCA052F

		byte[] bytes = parseHexToByte("AC4E1ADEF172BCA052F");
		System.out.println(Arrays.toString(bytes));

		// Ergebnis der Probe:
		// [-84, 78, 26, -34, -15, 114, -68, -96, 82, 15]
		// Passt (negative Zahlen (signed byte) umrechnen (zu unsigned byte),
		// dann stimmen die Zahlen überein)
	}

	public static byte[] parseHexToByte(String hex) {
		byte[] bytes = null;

		String[] hexArr = toHexArray(hex);
		bytes = new byte[hexArr.length];

		for(int i = 0; i < hexArr.length; i++) {
			bytes[i] = (byte)Integer.parseInt(hexArr[i], 16);
		}

		return bytes;
	}

	public static String[] toHexArray(String hex) {
		String[] hexArr = new String[(int)Math.ceil((double)hex.length() / 2)];

		for(int i = 0, j = 0; i < hexArr.length; i++, j += 2) {
			if(j + 2 > hex.length()) {
				hexArr[i] = "0" + hex.charAt(j);
			} else {
				hexArr[i] = hex.substring(j, j + 2);
			}
		}

		return hexArr;
	}
}
 
Zuletzt bearbeitet:
Zurück