使用 ImageIO.read 给出修改后的图像

Using ImageIO.read gives a modified image

我在 JLabels 中用图像做一些事情,我注意到我使用的一些图像(包含黑色的图像)在标签中比预期的更亮.图片是通过 ImageIO#read(File) 加载的。单独通过 ImageIcon 构造函数加载的图像看起来很正常。

这是我为这张图片拼凑的一个小测试:

JFrame frame = new JFrame();
frame.setLayout(new FlowLayout());
frame.setSize(320, 320);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

URL imageURL = new URL("https://wiki.factorio.com/images/Crude-oil.png");

frame.add(new JLabel(new ImageIcon(ImageIO.read(imageURL))));

frame.add(new JLabel(new ImageIcon(imageURL)));

frame.setVisible(true);

结果:

关于为什么会发生这种情况有什么想法吗?

这是已知的 bug,当 ImageIO.read() 未能找到图像的正确颜色模型时会发生。

相反,构造函数 ImageIcon(Url) 在使用 Toolkit.getDefaultToolkit().getImage(Url) 检索图像时正确显示图像。

此错误也可能发生在其他图片扩展上。参见 this

编辑

向下滚动并比较以下链接中 PNG 部分中的 颜色类型

http://regex.info/exif.cgi?imgurl=https://wiki.factorio.com/images/Crude-oil.png

http://regex.info/exif.cgi?imgurl=http://www.sherv.net/cm/emoticons/hand-gestures/victory-fingers-black-smiley-emoticon.png

除了图片都是 PNG 之外,您会看到两种颜色类型不同。 ImageIO.read() 的问题在于它可以正确读取 RGB with Alpha 但不能正确读取 Grayscale with Alpha.

我还发现 ImageIO.read().getType() returns 0 = TYPE_CUSTOM for the first image and 6 = TYPE_4BYTE_ABGR 第二个。 TYPE_CUSTOM 通常对于无法识别类型的图像返回。