处理图片时报异常信息 Invalid icc profile: duplicate sequence numbers

在对图片进行处理过程中,发现java 不支持 某些图片的操作(放大,缩小),报一下错误:

[ERROR][2024-03-18 11:23:04,661][com.elink.base.util.ImageUtil]error imgLoadUrl
javax.imageio.IIOException: Invalid icc profile: invalid number of icc markers
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(JPEGImageReader.java:628)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly(JPEGImageReader.java:347)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(JPEGImageReader.java:495)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(JPEGImageReader.java:621)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1078)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1058)
at javax.imageio.ImageIO.read(ImageIO.java:1462)
at javax.imageio.ImageIO.read(ImageIO.java:1309)
at com.elink.base.util.ImageUtil.imgLoadUrl(ImageUtil.java:190)
at com.elink.share.util.PdfHelper.image2pdfWithStamp(PdfHelper.java:69)

一般这些图片,是由扫描仪扫描,或者数码相机拍摄,并且处理时,图片的颜色空间(colorspace)为CMYK模式。
导致了ImageIO.read()方法抛出异常的原因。
一般情况为RGB模式。

在 sun 的官方网站,有该bug 的讨论:

更详细描述如下:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6245283
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6404011

在ImageIO.read方法前,把jpg图片文件从写,就不会有问题。.

        	     File srcImageFileGood = new File(dstImageFileName);    	
        		JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new FileInputStream(srcImageFile));    		
        		BufferedImage image = decoder.decodeAsBufferedImage();    	
        		ImageIO.write(image, "JPEG", srcImageFileGood);

原方法:

package com.elink.base.util;


import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageDecoder;
import org.apache.log4j.Logger;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class ImageUtil {

    private static Integer ROTATION_ANGLE = 360; //弧度

    private static Integer LOAD_NETWORK = 0; //图片来源网络

    private static Integer LOAD_LOCAL = 1; //图片来源本地

    private static Logger log = Logger.getLogger(ImageUtil.class);

    //测试
    public static void main(String[] args) {

//获取背景图
        BufferedImage bgImg = imgLoadUrl("E:/002.png", LOAD_LOCAL);
//需要叠加的图片列表
        List<ImgBean> imgBeans = new ArrayList<ImgBean>();
//需要添加的文字列表
        List<TextBean> textBeans = new ArrayList<TextBean>();

        //获取圆形图片 //margin=null 则不设置图片背景
//        BufferedImage circularImg = getCircularImg(imgLoadUrl("图片路径", LOAD_NETWORK), 30, 30, ROTATION_ANGLE, 20, Color.WHITE);

//        imgBeans.add(imgParameter(circularImg, true, null, 200, 300, 50));

        imgBeans.add(imgParameter(imgLoadUrl("E:/001_1.png", LOAD_LOCAL), true, null, bgImg.getHeight()/2-111, 222, 222));

//        textBeans.add(textParameter("需要输入的文字", true, null, 12, Color.white, new Font("微软雅黑", Font.PLAIN, 30)));

        try {
            ImageIO.write(createImg(bgImg, textBeans, imgBeans), "png", new File("E:/002_new.png"));
        } catch (IOException e) {
            log.error("error main", e);
        }

    }


    public static BufferedImage createImg(BufferedImage bgImg, List<TextBean> textBeans, List<ImgBean> imgBeans) {
        Graphics2D g = bgImg.createGraphics();
//去锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//图片叠加
        imgSuperposition(g, bgImg.getWidth(), imgBeans);
//添加文字
        textAddImg(g, bgImg.getWidth(), textBeans);
        return bgImg;

    }

    /**
     * 图片叠加
     *
     * @param g
     * @param
     * @param imgBeans
     */
    private static Graphics2D imgSuperposition(Graphics2D g, Integer bgImgWidth, List<ImgBean> imgBeans) {
        try {
            for (int i = 0; i < imgBeans.size(); i++) {
                ImgBean imgBean = imgBeans.get(i);
                if (imgBean.isCenter()) { //是否居中判断
                    int x = (bgImgWidth - imgBean.getW()) / 2;
                    g.drawImage(imgBeans.get(i).getImg(), x, imgBean.getY(), imgBean.getW(), imgBean.getH(), null);
                } else {
                    g.drawImage(imgBeans.get(i).getImg(), imgBean.getX(), imgBean.getY(), imgBean.getW(), imgBean.getH(), null);
                }
            }
        } catch (Exception e) {
            log.error("error imgSuperposition", e);
        }
        return g;
    }

    /**
     * 添加文字
     *
     * @param g
     * @param bgImgWidth
     * @param textBeans
     */
    private static Graphics2D textAddImg(Graphics2D g, Integer bgImgWidth, List<TextBean> textBeans) {
        try {
            for (int i = 0; i < textBeans.size(); i++) {
                TextBean textBean = textBeans.get(i);
                g.setColor(textBean.getColor());
                g.setFont(textBean.getFont());
                if (textBean.isCenter()) { //是否居中判断
                    int x = g.getFontMetrics().stringWidth(textBean.getName());
                    g.drawString(textBean.getName(), (bgImgWidth - x) / 2, textBean.getY());
                } else {
                    g.drawString(textBean.getName(), textBean.getX(), textBean.getY());
                }
            }
        } catch (Exception e) {
            log.error("error textAddImg", e);
        }

        return g;
    }


    /**
     * 图片圆形处理 返回处理后的图片
     *
     * @param img           图片
     * @param width         宽
     * @param height        高
     * @param rotationAngle 弧度
     * @param margin        边距 不传则不设置背景
     * @return
     */
    public static BufferedImage getCircularImg(BufferedImage img, Integer width, Integer height, Integer rotationAngle, Integer margin, Color color) {
        BufferedImage circularImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = circularImg.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.WHITE);
        g2.fill(new RoundRectangle2D.Float(0, 0, width, height, rotationAngle, rotationAngle));
        g2.setComposite(AlphaComposite.SrcAtop);
        g2.drawImage(img, 0, 0, width, height, null);
        g2.dispose();
        if (margin != null) {
            circularImg = getCircularImgByBorder(circularImg, margin, color);
        }
        return circularImg;
    }


    /**
     * 圆形图片添加圆形背景
     *
     * @param circularImg 传入的图
     * @param margin      边距
     * @param color       背景颜色
     * @return
     */
    public static BufferedImage getCircularImgByBorder(BufferedImage circularImg, Integer margin, Color color) {
        BufferedImage circularImgByBorder = new BufferedImage(circularImg.getWidth() + margin, circularImg.getHeight() + margin, circularImg.getType());
        Graphics2D g = circularImgByBorder.createGraphics();
//去锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setColor(color == null ? Color.WHITE : color);
        g.fill(new RoundRectangle2D.Float(0, 0, circularImg.getWidth() + margin, circularImg.getHeight() + margin, ROTATION_ANGLE, ROTATION_ANGLE));
        g.setComposite(AlphaComposite.SrcAtop);
        g.drawImage(circularImg, margin / 2, margin / 2, circularImg.getWidth(), circularImg.getHeight(), null);
        g.dispose();
        return circularImgByBorder;
    }

    /**
     * 获取图片
     *
     * @param imgUrl 图片路径
     * @param type   图片来源:0=网络/ 1=本地
     */
    public static BufferedImage imgLoadUrl(String imgUrl, Integer type) {
        try {
            try {
                return CMYK.readImage(imgUrl);
            }catch (Exception ex) {
                File srcImageFileGood = new File(imgUrl);
                JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new FileInputStream(imgUrl));
                BufferedImage image = decoder.decodeAsBufferedImage();
                ImageIO.write(image, "JPEG", srcImageFileGood);
                if (LOAD_NETWORK.equals(type)) {
                    return ImageIO.read(new URL(imgUrl));
                } else if (LOAD_LOCAL.equals(type)) {
                    return ImageIO.read(new File(imgUrl));
                }
            }
        } catch (Exception e) {
            log.error("error imgLoadUrl", e);
            try {
                JPEGImageDecoder decoder  = null;
                if (LOAD_LOCAL.equals(type)) {
                    decoder = JPEGCodec.createJPEGDecoder(new FileInputStream((new File(imgUrl))));
                }else if (LOAD_NETWORK.equals(type)) {
                    decoder = JPEGCodec.createJPEGDecoder(new URL(imgUrl).openStream());
                }
                return  decoder.decodeAsBufferedImage();
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 图片设置参数
     *
     * @param img    图片
     * @param center 是否居中
     * @param x      如果居中 此值可以不用传
     * @param y      图片y轴初始位置
     * @param w      图片宽
     * @param h      图片高
     */
    public static ImgBean imgParameter(BufferedImage img, boolean center, Integer x, Integer y, Integer w, Integer h) {
        try {
            ImgBean imgBean = new ImgBean();
            imgBean.setImg(img);
            imgBean.setCenter(center);
            imgBean.setX(x == null ? 0 : x);
            imgBean.setY(y == null ? 0 : y);
            imgBean.setW(w == null ? img.getWidth() : w);
            imgBean.setH(h == null ? img.getHeight() : h);
            return imgBean;
        } catch (Exception e) {
            log.error("error imgParameter", e);
        }
        return null;

    }

    /**
     * 文字设置参数
     *
     * @param name   传入文字
     * @param center 是否居中
     * @param x      x轴位置
     * @param y      y轴位置
     * @param color  颜色
     * @param font   画笔
     */
    public static TextBean textParameter(String name, boolean center, Integer x, Integer y, Color color, Font font) {
        try {
            TextBean textBean = new TextBean();
            textBean.setName(name);
            textBean.setCenter(center);
            textBean.setX(x == null ? 0 : x);
            textBean.setY(y == null ? 0 : y);
            textBean.setColor(color == null ? Color.WHITE : color);
            textBean.setFont(font == null ? new Font("微软雅黑", Font.PLAIN, 30) : font);
        } catch (Exception e) {
            log.error("error textParameter", e);
        }
        return null;
    }


    /**
     * 图片设置类
     * title imgParameter
     */
    public static class ImgBean {
        /**
         * 图片buffer
         */
        private BufferedImage img;
        /**
         * 图片x轴标
         */
        private int x;
        /**
         * 图片y轴坐标
         */
        private int y;
        /**
         * 图片宽
         */
        private int w;
        /**
         * 图片高
         */
        private int h;
        /**
         * 图片是否居中
         */
        private boolean center;

        public BufferedImage getImg() {
            return img;
        }

        public void setImg(BufferedImage img) {
            this.img = img;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }

        public int getW() {
            return w;
        }

        public void setW(int w) {
            this.w = w;
        }

        public int getH() {
            return h;
        }

        public void setH(int h) {
            this.h = h;
        }

        public boolean isCenter() {
            return center;
        }

        public void setCenter(boolean center) {
            this.center = center;
        }

    }

    /**
     * 文字bean
     * title TextBean
     */
    public static class TextBean {
        /**
         * 输入的文字
         */
        private String name;
        /**
         * 文字是否居中
         */
        private boolean center;
        /**
         * 文字的x轴位置
         */ //居中此值不用传
        private int x;
        /**
         * 文字的y轴位置
         */ //注:文字的位置计算是以文字的底部开始的,右下角,不像图片从左上角
        private int y;
        /**
         * 文字的颜色
         */
        private Color color;
        /**
         * 画笔
         */
        private Font font;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public boolean isCenter() {
            return center;
        }

        public void setCenter(boolean center) {
            this.center = center;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }

        public Color getColor() {
            return color;
        }

        public void setColor(Color color) {
            this.color = color;
        }

        public Font getFont() {
            return font;
        }

        public void setFont(Font font) {
            this.font = font;
        }


    }

}
  • 10
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值