2013-09-02 18 views
11

Ich habe eine Daten-URL aus einer Bilddatei und muss sie an eine andere Funktion übergeben. Entlang diesem Pfad von Data-URL zu BufferedImage muss es ein ByteArray sein.Konvertiere Daten-URL in BufferedImage

mein Ansatz war die folgende:

String dataUrl; 
byte[] imageData = dataUrl.getBytes(); 

// pass the byteArray along the path 

// create BufferedImage from byteArray 
BufferedImage inputImage = ImageIO.read(new ByteArrayInputStream(imageData)); 

// If the picture is null, then throw an unsupported image exception. 
if (inputImage == null) { 
    throw new UnknownImageFormatException(); 
} 

Das Problem ist, es wirft immer die UnknownImageFormatException Ausnahme, was bedeutet, inputImage null ist, was bedeutet, die ImageIO.read nicht die imagetype erkannte.

Ich habe ImageIO.getReaderFormatNames verwendet(), um die unterstützten Dateinamen zu erhalten und bekam die folgende Liste:

Supported Formats: 
jpg, BMP, bmp, JPG, jpeg, wbmp, png, JPEG, PNG, WBMP, GIF, gif 

Die dataURLs Ich versuche, sind zu passieren wie: data:image/png;base64,... oder data:image/jpg;base64,...

Soweit Ich verstehe, dass diese in der unterstützten Dateiliste sind und daher erkannt werden sollten.

Was könnte sonst dazu führen, dass das inputImage in diesem Fall null ist? Und interessanter, wie löse ich es?

+3

Sie müssen den String von base64 zurück in ein Binärformat dekodieren, das ImageIO lesen kann, oder, wenn Sie ein URL-Objekt haben, leiten Sie es direkt an ImageIO – MadProgrammer

+2

Weiter zum Rat von @MadProgrammer können Sie den [' DatatypeConverter '] (http://docs.oracle.com/javase/7/docs/api/javax/xml/bind/DatatypeConverter.html#method_summary), um die Basis-64-Zeichenfolge zurück in ein 'byte []' zu konvertieren. –

Antwort

16

Wie die Kommentare bereits gesagt, sind die Bilddaten Base64-codiert. Um die Binärdaten abzurufen, müssen Sie die Typ-/Codierungs-Header entfernen und den Base64-Inhalt in Binärdaten dekodieren.

String encodingPrefix = "base64,"; 
int contentStartIndex = dataUrl.indexOf(encodingPrefix) + encodingPrefix.length(); 
byte[] imageData = Base64.decodeBase64(dataUrl.substring(contentStartIndex)); 

Ich benutze org.apache.commons.codec.binary.Base64 von apaches Common-Codec, andere Base64 Decoder sollte auch funktionieren.

+5

Ab Java 8 gibt es im Core-JDK einen Base64-Encoder/Decoder: http://download.java.net/jdk8/docs/api/java/util/Base64.html – Jules

3

Das einzige Problem mit RFC2397-String ist die Spezifikation mit allem, bevor die Daten aber data: und , optional:

data:[<mediatype>][;base64],<data> 

So reine Java-8-Lösung Buchhaltung dies wäre:

final int dataStartIndex = dataUrl.indexOf(",") + 1; 
final String data = dataUrl.substring(dataStartIndex); 
byte[] decoded = java.util.Base64.getDecoder().decode(data); 

Natürlich dataStartIndex sollte überprüft werden.