将数据 URL 转换为缓冲图像

我有一个来自图像文件的数据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 无法识别图像类型。

我使用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,...

据我所知,这些都在支持的文件列表中,因此应该得到认可。

在这种情况下,还有什么可能导致输入图像为空?更有趣的是,我该如何解决它?


答案 1

正如评论已经说过的那样,图像数据是Base64编码的。要检索二进制数据,您必须去除类型/编码标头,然后将 Base64 内容解码为二进制数据。

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

我使用apache的通用编解码器,其他Base64解码器也应该可以正常工作。org.apache.commons.codec.binary.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。


推荐