我有一个来自图像文件的数据URL,必须将其传递给另一个函数。沿着从Data-URL到BufferedImage的这条路径,它需要是一个byteArray。
我的方法如下:
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 Exception,这意味着inputImage为null,这意味着,ImageIO.read无法识别imagetype。
我使用了ImageIO.getReaderFormatNames()来获取支持的文件名并得到以下列表:
Supported Formats:
jpg, BMP, bmp, JPG, jpeg, wbmp, png, JPEG, PNG, WBMP, GIF, gif
我尝试传递的dataURL如:data:image/png;base64,...
或data:image/jpg;base64,...
据我了解,这些都在受支持的文件列表中,因此应该被识别。
在这种情况下还有什么可能导致inputImage为null?更有趣的是,我该如何解决?
答案 0 :(得分:20)
由于评论已经说过图像数据是Base64编码的。要检索二进制数据,您必须删除类型/编码标头,然后将Base64内容解码为二进制数据。
String encodingPrefix = "base64,";
int contentStartIndex = dataUrl.indexOf(encodingPrefix) + encodingPrefix.length();
byte[] imageData = Base64.decodeBase64(dataUrl.substring(contentStartIndex));
我使用apache common-codec中的org.apache.commons.codec.binary.Base64
,其他Base64解码器也可以正常工作。
答案 1 :(得分:8)
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。
答案 2 :(得分:0)
我认为,简单的正则表达式替换会更好,并且更符合RFC2397:
java.util.Base64.getDecoder().decode(b64DataString.replaceFirst("data:.+,", ""))
RFC指出data:
和,
是数据URL的必需前缀,因此明智的做法是将它们匹配。