兼容ImageIO读取jpeg图片变红

使用ImageIO.read()方法,加载图片为BufferedImage对象时,对于某些图片,会出现变红的case

问题重现

有问题的图片: img

测试验证代码

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 图片读取之后,颜色变红的测试
*/
@Test
public void testLoadRedImg() throws IOException {
String url = "http://s17.mogucdn.com/mlcdn/c45406/170418_68lkjddg3bll08h9c9bk0d8ihkffi_800x1200.jpg";
URL u = new URL(url);
BufferedImage bf = ImageIO.read(u);
ImageIO.write
System.out.println("--over--");

}

debug截图如下:

FFC31217-6457-46BD-9DB4-3C0632C2AE07.png

问题兼容

不实用ImageIO来加载图片,改用Toolkit来实现图片读取,然后再将读取到的图片绘制到BufferedImage对象上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Test
public void testLoadRedImg2() throws MalformedURLException {
String url = "http://s17.mogucdn.com/mlcdn/c45406/170418_68lkjddg3bll08h9c9bk0d8ihkffi_800x1200.jpg";
URL u = new URL(url);
Image img = Toolkit.getDefaultToolkit().getImage(u);
BufferedImage bf = toBufferedImage(img);
System.out.println("eeee");
}


static BufferedImage toBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage) image;
}
// This code ensures that all the pixels in the image are loaded
image = new ImageIcon(image).getImage();
BufferedImage bimage = null;
GraphicsEnvironment ge = GraphicsEnvironment
.getLocalGraphicsEnvironment();
try {
int transparency = Transparency.OPAQUE;
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
bimage = gc.createCompatibleImage(image.getWidth(null),
image.getHeight(null), transparency);
} catch (HeadlessException e) {
// The system does not have a screen
}
if (bimage == null) {
// Create a buffered image using the default color model
int type = BufferedImage.TYPE_INT_RGB;
bimage = new BufferedImage(image.getWidth(null),
image.getHeight(null), type);
}
// Copy image to buffered image
Graphics g = bimage.createGraphics();
// Paint the image onto the buffered image
g.drawImage(image, 0, 0, null);
g.dispose();
return bimage;
}

实测验证

4871A1EA-A9FC-46A8-9C9D-954B93978435.png

为什么会出现这个问题:

ImageIO.read()方法读取图片时可能存在不正确处理图片ICC信息的问题,ICC为JPEG图片格式中的一种头部信息,导致渲染图片前景色时蒙上一层红色。

其他

参考

扫描关注,java分享

QrCode