digdeep

凡是过去,皆是序幕。Read the fucking manual and source code.

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

javax.imageio.IIOException: Invalid icc profile: duplicate sequence numbers

图片文件上传代码如下:

BufferedInputStream in = new BufferedInputStream(file.getInputStream());

BufferedImage bi = ImageIO.read(in); 

 

BufferedImage bi = ImageIO.read(in); 这一行突然报错:

javax.imageio.IIOException: Invalid icc profile: duplicate sequence numbers
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(JPEGImageReader.java:620)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(JPEGImageReader.java:347)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(JPEGImageReader.java:492)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(JPEGImageReader.java:613)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1070)
	at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1050)
	at javax.imageio.ImageIO.read(ImageIO.java:1448)
	at javax.imageio.ImageIO.read(ImageIO.java:1352)

图片解析异常:Invalid icc profile: duplicate sequence numbers

异常核心原因

这是JPEG 图片本身的 ICC 色彩配置文件损坏 / 不标准导致的:
 
图片里的ICC Profile(色彩配置文件)存在重复的序列号,Java 自带的 ImageIO 解析器无法识别这种非标准、损坏的 JPEG 文件,直接抛出异常。
简单说:图片文件是坏的 / 格式不标准,Java 读不了。
解决办法:
 
BufferedImage bi = ImageIO.read(in); 
换成:
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

public class ImageUtil {

    public static BufferedImage readImage(InputStream inputStream) throws IOException {
        // 读取流为字节数组,防止流只能读一次
        byte[] bytes = toByteArray(inputStream);
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

        BufferedImage image;
        try {
            // 正常图片读取
            image = ImageIO.read(bais);
        } catch (Exception e) {
        	e.printStackTrace();
            // 处理ICC异常图片
            Image rawImage = Toolkit.getDefaultToolkit().createImage(bytes);
            // 强制等待图片加载完成(解决宽高-1问题)
            Image loadedImage = new ImageIcon(rawImage).getImage();

            int width = loadedImage.getWidth(null);
            int height = loadedImage.getHeight(null);

            if (width <= 0 || height <= 0) {
                throw new IOException("图片已损坏,无法解析");
            }

            // JDK8 正确写法:手动关闭 Graphics2D
            image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = image.createGraphics();
            g2d.drawImage(loadedImage, 0, 0, null);
            g2d.dispose(); // 手动释放资源
        }

        if (image == null) {
            throw new IOException("不支持的图片格式或文件已损坏");
        }
        return image;
    }

    // JDK8 流转字节数组
    private static byte[] toByteArray(InputStream is) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int len;
        while ((len = is.read(buffer)) != -1) {
            baos.write(buffer, 0, len);
        }
        return baos.toByteArray();
    }
}

 解决问题。 

系统运行了好几年,突然有个用户反馈报错。报错的核心原因是图片格式非法。 

 

 

posted on 2026-06-05 15:17  digdeep  阅读(2)  评论(0)    收藏  举报
不懂数据库和Web安全的架构师不是一个好的程序员。