为什么使用 ImageIO 无法从 URL 获取 BufferedImage

Why use ImageIO can't get BufferedImage from URL

图片网址:https://fbexternal-a.akamaihd.net/safe_image.php?d=AQBB77GLfY75FNWL&w=720&h=2048&url=http%3A%2F%2Fwww.facebook.com%2Fads%2Fimage%2F%3Fd%3DAQI0duFYFcmydWNutbwmSk2DfOmHcDrhPfsMJTUoEObbWkVzYUtrHgCuN_LFrWcPRzJi6jPgbn80oFs0Kj_WrdROjdnJkjbnS5-UJv9l9cJyhKCWS-lr-MXlc263Ul3Txe-VFqXfRrA6BOjt4DF-Sww2&ext=best

URL url = new URL(imageURL);
BufferedImage image = ImageIO.read(url);

URL url = new URL(imageURL);
BufferedImage image = ImageIO.read(url.openStream());

结果图片为空?为什么?

当我在 Firefox 中打开 link 时,它会尝试下载名为 "safe_image.php" 的文件。它适用于 Google Chrome,因此 headers 或 URL 中发生了一些奇怪的事情。有什么办法可以在别处托管图像吗?

编辑:您的图像似乎是 WebP 格式。 ImageIO 本身不支持这种格式,所以你需要一个像 webp-imageio.

这样的库

安装该库并查看您的代码是否有效。 ImageIO 应该会在您 运行 ImageIO.scanForPlugins().

时自动找到插件

确保您提供的 URL 链接到有效的图像文件格式,例如 jpgpngbmp 等。

您当前的 URL 正在链接到一个 .php 文件,这显然不是图像。

例如:

public static void main(String[] args)
{     
    Image image = null;
    try {
        URL url = new URL("https://s-media-cache-ak0.pinimg.com/236x/ac/bb/d4/acbbd49b22b8c556979418f6618a35fd.jpg");
        image = ImageIO.read(url);
    } catch (IOException e) {
        e.printStackTrace();
    }

    JFrame frame = new JFrame();
    frame.setSize(236, 306);
    frame.add(new JLabel(new ImageIcon(image)));
    frame.setVisible(true);                 
}

ImageIO.read(URL) 确实支持从 URL 中读取图像,就像您描述的那样,但是,它确实只支持一组有限的图像格式。内置格式为 JPEG、PNG、GIF、BMP 和 WBMP。还有许多其他格式的插件,如 TIFF、JPEG 2000 等。

问题是链接的图像不是任何内置格式,它是 WEBP format,一种由 Google 创建的新图像格式,并且没有很普遍使用呢。它在您的浏览器(和我的 :-) 中显示良好的原因很可能是您使用的是 Chrome,并且 Chrome 内置了对 WEBP 的支持。

至少有一个 WEBP ImageIO plugin 可用。如果您构建并安装了这个插件,您上面的代码应该可以正常工作并且可以很好地读取图像。如果启动应用程序时插件在 class 路径上,则无需调用 ImageIO.scanForPlugins()