【imagemagick】 java 整合 imagemagick使用总结

入门


支持很多种图片格式。
先去官网下载安装包安装到自己的电脑上面, 如果是服务器使用, 让服务器安装。
引入依赖:
我采用的gradle
implementation ‘org.im4java:im4java:1.4.0’

编写工具类

public class ImageMagickHandler {
	private final String imageMagickPath;
    public ImageMagickHandler(String imageMagickPath){
        this.imageMagickPath = imageMagickPath;
    }

    @Getter
    enum CommandType {
        convert("转换处理"),composite("图片合成"),identify("图片信息");
        private final String des;

        CommandType(String des) {
            this.des = des;
        }
    }
    @Getter
    public enum GravityType{
        northwest("左上","TOP_START"),west("左侧居中","CENTER_START"),southwest("左下","BOTTOM_START"),
        north("顶部居中","TOP"),center("居中","CENTER"),south("底部居中","BOTTOM"),
        northeast("右上","TOP_END"),east("右侧居中","CENTER_END"),southeast("右下","BOTTOM_END");
        private final String des;
        private final String name;
        GravityType(String des,String name) {
            this.des = des;
            this.name = name;
        }
        public static GravityType getInfo(String name){
            for (GravityType gravityType : values()) {
                if(gravityType.getName().equals(name)){
                    return gravityType;
                }
            }
            return null;
        }
    }
    @Data
    @ToString
    public static class ImageInfo{
        private Integer width;
        private Integer height;
        private String path;
        private Integer quality;
        private String size;
        private String format;
        private Integer frames;

        public ImageInfo(Integer width, Integer height, String path, Integer quality, String size, String format,Integer frames) {
            this.width = width;
            this.height = height;
            this.path = path;
            this.quality = quality;
            this.size = size;
            this.format = format;
            this.frames = frames;
        }
    }
    private ImageCommand getImageCommand(CommandType commandType){
        ImageCommand convertCmd = null;
        switch (commandType){
            case convert:
                convertCmd =new ConvertCmd();
                break;
            case composite:
                convertCmd =new CompositeCmd();
                break;
            case identify:
                convertCmd =new IdentifyCmd();
                break;
        }
        //windows 需要, linux不需要
        if(ObjectUtil.isNotEmpty(convertCmd)){
            if(ObjectUtil.isNotEmpty(this.imageMagickPath)){
                convertCmd.setSearchPath(this.imageMagickPath);
            }
        }
        return convertCmd;
    }

    /****
     * 获取图片信息
     * @param imagePath 原图地址
     * @return 返回图片信息
     */
    public ImageInfo getImageInfo(String imagePath) {
        ImageInfo imageInfo = null;
        try {
            IMOperation op = new IMOperation();
            op.format(",%w,%h,%d/%f,%Q,%B,%e");
            op.addImage(imagePath);
            ImageCommand identifyCmd = getImageCommand(CommandType.identify);//注意这里,用的是identify
            ArrayListOutputConsumer output = new ArrayListOutputConsumer();
            identifyCmd.setOutputConsumer(output);
            identifyCmd.run(op);
            ArrayList<String> cmdOutput = output.getOutput();
            String[] result = cmdOutput.get(0).split(",");
            if (result.length >= 7) {
                String path=result[3];
                int frames=0;
                for (String s : result) {
                    if(path.equals(s)){
                        frames++;
                    }
                }
                imageInfo= new ImageInfo(Integer.parseInt(result[1]),
                        Integer.parseInt(result[2]),
                        result[3],
                        Integer.parseInt(result[4]),
                        result[5],
                        result[6],
                        frames);
            }
        } catch (Exception e) {
            log.error("获取图片信息异常:{}", e);
        }
        return imageInfo;
    }

    /***
     * 仅支持 jpeg,jpg,png,以及静态的webp
     * 水印图片-不支持动态图片 比如gif,webp,
     * 不支持psd,tiff,svg,ico
     * @param srcImagePath 原图
     * @param newImagePath 生成水印的新图
     * @param appendImagePath 水印图
     * @param gravityType 位置
     * @param horizontalMargin 横向边距
     * @param longitudinalMargin 纵向边距
     * @param size 水印大小
     * @return 成功还是失败
     */
    public boolean compositeImage(String srcImagePath, String newImagePath,String appendImagePath,GravityType gravityType,
                                          int horizontalMargin,int longitudinalMargin,int size,int w1, int h1){
        try {
            IMOperation op = new IMOperation();
            /*op.gravity(gravityType.name());
            op.compose("plus");
            op.geometry(w1, h1,longitudinalMargin,horizontalMargin);
            //op.geometry(w1, h1, w-w1-margin, h-h1-margin);
            //op.dissolve(dissolve);
            op.addImage(appendImagePath);
            op.addImage(srcImagePath);
            op.addImage(newImagePath);*/
            //op.coalesce();
            op.addImage(srcImagePath);
            //op.alpha("Set");
            //op.dither("None");
            op.gravity(gravityType.name());
            op.geometry(w1, h1,longitudinalMargin,horizontalMargin);
            op.addRawArgs("null:",appendImagePath);
            //op.draw("'image over "+w1+","+h1+" "+longitudinalMargin+","+horizontalMargin+" \""+appendImagePath+"\"'");
            //op.geometry(longitudinalMargin,horizontalMargin);
            //op.addImage(appendImagePath);
            op.layers("composite");
            //op.layers("optimize");//这种模式会降低图片质量
            //op.layers("Flatten");//保持质量 会比原图更好
            op.addImage(newImagePath);
            ImageCommand composite = getImageCommand(CommandType.convert);
            composite.run(op);
        }catch (Exception e){
            log.error("水印失败异常:{}", e);
            return false;
        }
        return true;
    }

    /**
     * 设置图片颜色色彩空间为RGB模式
     *
     * @param srcImagePath
     * @param targetPath
     * @return
     */
    public boolean colorSpaceRGB(String srcImagePath, String targetPath) {
        try {
            IMOperation op = new IMOperation();
            op.addImage(srcImagePath);
            op.colorspace("sRGB");
            op.addImage(targetPath);
            ImageCommand composite = getImageCommand(CommandType.convert);
            composite.run(op);
        } catch (Exception e) {
            log.error("色彩空间RGB失败异常:{}", e);
            return false;
        }
        return true;
    }

    /***
     * 仅支持 jpeg,jpg,png,以及静态的webp
     * 水印图片-不支持动态图片 比如gif,webp,
     * 不支持psd,tiff,svg,ico
     * @param srcImagePath 原图
     * @param newImagePath 生成水印的新图
     * @param appendImagePath 水印图
     * @param gravityType 位置
     * @param horizontalMargin 横向边距
     * @param longitudinalMargin 纵向边距
     * @param size 水印大小
     * @return 成功还是失败
     */
    public boolean compositeAnimatedImage(String srcImagePath, String newImagePath,String appendImagePath,GravityType gravityType,
                                          int horizontalMargin,int longitudinalMargin,int size,int w1, int h1){
        try {

            IMOperation op = new IMOperation();
            op.coalesce();
            op.addImage(srcImagePath);
            op.gravity(gravityType.name());
            op.geometry(w1, h1,longitudinalMargin,horizontalMargin);
            op.addRawArgs("null:",appendImagePath);
            //op.draw("'image over "+w1+","+h1+" "+longitudinalMargin+","+horizontalMargin+" \""+appendImagePath+"\"'");
            //op.geometry(longitudinalMargin,horizontalMargin);
            //op.addImage(appendImagePath);
            op.layers("composite");
            op.layers("optimize");
            op.addImage(newImagePath);
            ImageCommand composite = getImageCommand(CommandType.convert);
            composite.run(op);
        }catch (Exception e){
            log.error("水印失败异常:{}", e);
            return false;
        }
        return true;
    }
    /****
     * 压缩尺寸-支持各种格式不包含动态图片
     * @param imagePath 原图地址
     * @param newImagePath 新图地址
     * @param width 指定宽度
     * @return 成功还是失败
     */
    public boolean compress(String imagePath,String newImagePath,int width){
        try {
            IMOperation imOperation = new IMOperation();
            imOperation.addImage(imagePath);
            //imOperation.coalesce();
            imOperation.resize(width);
            imOperation.colorspace("sRGB");
            imOperation.layers("coalesce");
            imOperation.addImage(newImagePath);
            ImageCommand convertCmd = getImageCommand(CommandType.convert);
            convertCmd.run(imOperation);
        }catch (Exception e){
            log.error("压缩失败异常:{}", e);
            return false;
        }
        return true;
    }

    /****
     * 压缩尺寸-支持各种格式不包含动态图片
     * @param imagePath 原图地址
     * @param newImagePath 新图地址
     * @param width 指定宽度
     * @param width 指定高度
     * @return 成功还是失败
     */
    public boolean compress(String imagePath,String newImagePath,int width,int height){
        try {
            IMOperation imOperation = new IMOperation();
            imOperation.addImage(imagePath);
            //imOperation.coalesce();
            imOperation.resize(width,height);
            imOperation.layers("coalesce");
            imOperation.addImage(newImagePath);
            ImageCommand convertCmd = getImageCommand(CommandType.convert);
            convertCmd.run(imOperation);
        }catch (Exception e){
            log.error("压缩失败异常:{}", e);
            return false;
        }
        return true;
    }
    /****
     * 压缩尺寸-支持gif,webp 动态图片
     * @param imagePath 原图地址
     * @param newImagePath 新图地址
     * @param width 指定宽度
     * @return 成功还是失败
     */
    public boolean compressGifAndWebp(String imagePath,String newImagePath,int width){
        try {
            IMOperation imOperation = new IMOperation();
            imOperation.addImage(imagePath);
            imOperation.coalesce();
            imOperation.resize(width);
            imOperation.addImage(newImagePath);
            ImageCommand convertCmd = getImageCommand(CommandType.convert);
            convertCmd.run(imOperation);
        }catch (Exception e){
            log.error("水印失败异常:{}", e);
            return false;
        }
        return true;
    }

    /***
     * 设置图片透明度
     * @param imagePath
     * @param newImagePath
     * @param dissolve
     * @return
     */
    public boolean opacityImage(String imagePath,String newImagePath,int dissolve){
        try {
            IMOperation imOperation = new IMOperation();
            imOperation.addImage(imagePath);
            imOperation.alpha("set");
            imOperation.channel("A");
            imOperation.evaluate("set",dissolve+"%");
            imOperation.addImage(newImagePath);
            ImageCommand convertCmd = getImageCommand(CommandType.convert);
            convertCmd.run(imOperation);
        }catch (Exception e){
            log.error("设置透明度失败异常:{}", e);
            return false;
        }
        return true;
    }

    /***
     * 转换图片格式
     * @param imagePath 原图片
     * @param newImagePath 转换的图片
     * @param imageFormat 图片格式
     * @return
     */
    public boolean convertFormat(String imagePath,String newImagePath,String imageFormat){
        try {
            IMOperation imOperation = new IMOperation();
            imOperation.addImage(imagePath);
            imOperation.quality(100d);
            imOperation.addImage(imageFormat);
            imOperation.addImage(newImagePath);
            ImageCommand convertCmd = getImageCommand(CommandType.convert);
            convertCmd.run(imOperation);
        }catch (Exception e){
            log.error("转换图片格式失败异常:{}", e);
            return false;
        }
        return true;
    }

    /****
     * 裁剪
     * @param imagePath 原图
     * @param newImagePath 新图
     * @param x x坐标
     * @param y y坐标
     * @param width 宽
     * @param height 高
     * @return 成功还是失败
     */
    public boolean crop(String imagePath,String newImagePath,int x,int y,int width,int height){
        try {
            IMOperation imOperation = new IMOperation();
            imOperation.addImage(imagePath);
            imOperation.crop(width,height,x,y);
            imOperation.addImage(newImagePath);
            ImageCommand convertCmd = getImageCommand(CommandType.convert);
            convertCmd.run(imOperation);
        }catch (Exception e){
            log.error("裁剪失败异常:{}", e);
            return false;
        }
        return true;
    }

    /***
     * 格式转换,如果是动态图转png就会生成多张静态图
     * @param imagePath 原图
     * @param newImagePath 新图
     * @return 成功还是失败
     */
    public boolean toFormat(String imagePath,String newImagePath){
        try {
            IMOperation imOperation = new IMOperation();
            imOperation.addImage(imagePath);
            imOperation.layers("coalesce");
            imOperation.addImage(newImagePath);
            ImageCommand convertCmd = getImageCommand(CommandType.convert);
            convertCmd.run(imOperation);
        }catch (Exception e){
            log.error("格式转换失败异常:{}", e);
            return false;
        }
        return true;
    }

    /***
     * 合并操作
     * 用于多张图合成一张图, 常用于水印gif,webp动态图
     * @param srcList
     * @param newImagePath
     * @return
     */
    public boolean merge(List<String> srcList,String newImagePath){
        try {
            IMOperation imOperation = new IMOperation();
            imOperation.delay(0);
            for (String imagePath : srcList) {
                imOperation.addImage(imagePath);
            }
            imOperation.loop(0);
            imOperation.addImage(newImagePath);
            ImageCommand convertCmd = getImageCommand(CommandType.convert);
            convertCmd.run(imOperation);
        }catch (Exception e){
            log.error("合并失败异常:{}", e);
            return false;
        }
        return true;
    }

    

    /***
     * 转32位
     * @param srcImagePath
     * @param newImagePath
     * @return
     */
    public boolean to32Bit(String srcImagePath,String newImagePath){
        try {
            IMOperation op = new IMOperation();
            op.addImage(srcImagePath);
            op.depth(32);
            op.addImage(newImagePath);
            ImageCommand convertCmd = getImageCommand(CommandType.convert);
            convertCmd.run(op);
        }catch (Exception e){
            log.error("转32bit失败异常:{}", e);
            return false;
        }
        return true;
    }
}
/**
     * 设置透明度
     * @param path
     * @param out
     * @param alphaPercentage
     */
    public void adjustTransparency(String path,String out, int alphaPercentage) {
        try{
            BufferedImage image = ImageIO.read(new File(path));
            // 计算新的透明度值
            float alpha = (float) (alphaPercentage / 100.0);
            // 创建一个新的图片,透明度被应用到所有的像素上
            int type = image.getType();
            if(type==0){
                type=BufferedImage.TYPE_INT_ARGB;
            }
            BufferedImage adjustedImage = new BufferedImage(image.getWidth(), image.getHeight(), type);
            Graphics2D g2d = adjustedImage.createGraphics();

            // 设置新的透明度
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));

            // 绘制原始图片
            g2d.drawImage(image, 0, 0, null);
            g2d.dispose();
            ImageIO.write(adjustedImage, "PNG", new File(out));
            adjustedImage.flush();
        }catch (IOException e){
            log.error("图片设置透明度失败异常:{}", e);
            throw new BusinessException("图片设置透明度失败", e);
        }
    }

注意:
1.在使用的时候, window 使用 要配置imagemagick安装地址
2.linux 上面使用不需要配置imagemagick安装地址
3.在处理图片的时候,要看图片的深度位是多少。
4. 图片的色彩空间也要主要, 不然水印的时候,图片会变色
5. 水印的时候, 不用使用-layers optimize,该参数会导致图片质量降低。
6. 需要设置图片透明度, 我没有使用imagemagick的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值