2013-09-02 23 views
11

Ho un URL dati da un file immagine e devo passarlo a un'altra funzione. Lungo questo percorso da Data-URL a BufferedImage deve essere un byteArray.Converti dati-URL in bufferImmagine

il mio approccio è stato il seguente:

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(); 
} 

Il problema è, si getta sempre l'eccezione UnknownImageFormatException, il che significa che inputImage è nullo, il che significa, l'ImageIO.read non ha riconosciuto l'imagetype.

Ho usato ImageIO.getReaderFormatNames() per ottenere i nomi dei file supportati ed ha ottenuto il seguente elenco:

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

I dataURLs provo a passare sono come: data:image/png;base64,... o data:image/jpg;base64,...

Per quanto riguarda Capisco, quelli sono nella lista dei file supportati e quindi dovrebbero essere riconosciuti.

Cos'altro potrebbe causare l'inputImage in questo caso? E più interessante, come lo risolvo?

+3

È necessario decodificare la stringa da base64 a un formato binario che ImageIO può leggere, oppure, se si dispone di un oggetto URL, magari passare direttamente a ImageIO – MadProgrammer

+2

Oltre al consiglio di @MadProgrammer è possibile utilizzare il [' DatatypeConverter'] (http://docs.oracle.com/javase/7/docs/api/javax/xml/bind/DatatypeConverter.html#method_summary) per convertire la stringa 64 di base in un 'byte []'. –

risposta

16

Come già detto, i dati dell'immagine sono codificati Base64. Per recuperare i dati binari è necessario rimuovere le intestazioni di tipo/codifica, quindi decodificare il contenuto Base64 in dati binari.

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

Io uso org.apache.commons.codec.binary.Base64 da apaches common-codec, altri decoder Base64 dovrebbero funzionare così.

+5

A partire da Java 8, c'è un codificatore/decodificatore Base64 nel core JDK: http://download.java.net/jdk8/docs/api/java/util/Base64.html – Jules

3

L'unico problema con la stringa RFC2397 è la sua specifica con tutto prima che i dati, ma data: e , opzionale:

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

Così puro soluzione Java 8 contabilità questo sarebbe:

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

Naturalmente dataStartIndex dovrebbe essere controllato.