Преобразование URL-адреса данных в BufferedImage

У меня есть URL-адрес данных из файла изображения и должен передать его другой функции. По этому пути от URL-адреса данных к BufferedImage он должен быть байтом.

мой подход был следующим:

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

Проблема заключается в том, что она всегда выдает исключение UnknownImageFormatException, что означает, что inputImage имеет значение null, а значит, ImageIO.read не распознал тип imagetype.

Я использовал ImageIO.getReaderFormatNames(), чтобы получить поддерживаемые имена файлов и получил следующий список:

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

ДанныеURL, которые я пытаюсь передать, похожи на: data:image/png;base64,... или data:image/jpg;base64,...

Насколько я понимаю, они находятся в поддерживаемом списке файлов и поэтому должны быть распознаны.

Что еще может привести к тому, что inputImage будет null в этом случае? И еще интереснее, как мне его решить?

Ответ 1

Как уже отмечалось, данные изображения кодируются Base64. Чтобы получить двоичные данные, вы должны лишить заголовки типов/кодировок, затем декодировать содержимое Base64 на двоичные данные.

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

Я использую org.apache.commons.codec.binary.Base64 из общепринятого кодека apaches, другие декодеры Base64 также должны работать.

Ответ 2

Единственная проблема с строкой RFC2397 - это ее спецификация со всем, кроме данных, но data: и , необязательно:

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

Таким чистым решением для Java 8 это будет:

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

Конечно, dataStartIndex следует проверить.