Im4java 操作 ImageMagick 处理图片

转载于:Im4java 操作 ImageMagick 处理图片 - 一线大码 - 博客园 (cnblogs.com)

项目描述

ImageMagic的安装可参考:图片处理软件 ImageMagick 的安装和使用

Im4java是ImageMagick的第二个java接口。它不是JMagick的替代品,而是作为补充。

JMagick是ImageMagick C-API之上的瘦JNI层。相比之下,im4java只为ImageMagick命令生成命令行,并将生成的命令行传递给选定的IM命令(使用java.lang.ProcessBuilder.start() - 方法)。

im4java的缺点:您仅限于IM命令的功能。使用JMagick,您可以访问IM的低级接口,所以您可以非常详细地控制图像处理。图像处理会有更好的表现。

im4java的优点:IM命令行的界面非常稳定,因此你的java程序(和im4java-library)可以在很多版本的IM上运行。im4java还提供了更好的OO接口(IM命令行的“语言”,其后缀操作符号很容易转换为OO符号)。最重要的是:你可以在任何地方使用im4java,而JMagick在某些地方会因为JNI的危险性而无法使用 (例如java应用程序服务器)。

注意事项

我用的ImageMagick版本是ImageMagick-7.0.8-12-Q16-x64-dll.exe,安装完后发现安装目录里只有个 magick.exe 命令。程序里直接使用convert,composite,identify的时候都会报错,提示文件找不到。新版本使用这些命令必须先写上 magick 命令才行,比如这样 magick convert xxxx。原因可能是ImageMagick版本更新了,但是Im4java版本没更新(Im4java版本是1.4.0),导致出现不兼容的情况,解决办法很简单,直接把 magick.exe 复制三份,重命名为其他三个命令就可以了,实测可用。

 

<dependency>
    <groupId>org.im4java</groupId>
    <artifactId>im4java</artifactId>
    <version>1.4.0</version>
</dependency> 

 

package imagemagick;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import org.im4java.core.CompositeCmd;
import org.im4java.core.ConvertCmd;
import org.im4java.core.IMOperation;
import org.im4java.core.IdentifyCmd;
import org.im4java.core.ImageCommand;
import org.im4java.process.ArrayListOutputConsumer;

public class Im4JavaUtils {

    private static final String IMAGE_MAGICK_PATH = "D:\\ImageMagick-7.0.8-Q16";

    enum CommandType{

        convert("转换处理"),composite("图片合成"),identify("图片信息"),;
        private String name;

        CommandType(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

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

    }

    private static ImageCommand getImageCommand(CommandType command) {
        ImageCommand cmd = null;
        switch (command) {
        case convert:
            cmd = new ConvertCmd();
            break;
        case composite:
            cmd = new CompositeCmd();
            break;
        case identify:
            cmd = new IdentifyCmd();
            break;
        }
        if (cmd != null) {
            cmd.setSearchPath(IMAGE_MAGICK_PATH);
        }
        return cmd;
    }

    /**
     * 旋转图片
     * @param srcImagePath 原图片地址
     * @param newImagePath 新图片地址
     * @param degree 旋转角度
     * @return
     */
    public static boolean roateImage(String srcImagePath, String newImagePath, Double degree){
        try {
            IMOperation op = new IMOperation();
            op.addImage(srcImagePath);
            op.rotate(degree);
            op.addImage(newImagePath);
            ImageCommand convert = getImageCommand(CommandType.convert);
            convert.run(op);
            System.out.println("旋转图片成功");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 裁剪图片
     * @param srcImagePath 原图片地址
     * @param newImagePath 新图片地址
     * @param width 裁剪后的宽度
     * @param height 裁剪后的高度
     * @param x 起始横坐标
     * @param y 起始纵坐标
     * @return
     */
    public static boolean cutImage(String srcImagePath, String newImagePath, Integer width, Integer height, Integer x, Integer y) {
        try {
            IMOperation op = new IMOperation();
            op.addImage(srcImagePath);
            op.crop(width, height, x, y);
            op.addImage(newImagePath);
            ImageCommand convert = getImageCommand(CommandType.convert);
            convert.run(op);
            System.out.println("裁剪图片成功");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 缩放图片
     * @param srcImagePath 原图片地址
     * @param newImagePath 新图片地址
     * @param width 缩放后的宽度
     * @param height 缩放后的高度
     * 高度和宽度需符合图片比例,不符合的情况下,以其中最小值为准。
     * @return
     */
    public static boolean zoomImage(String srcImagePath, String newImagePath, Integer width, Integer height) {
        try {
            IMOperation op = new IMOperation();
            op.addImage(srcImagePath);
            op.resize(width, height);
            op.addImage(newImagePath);
            ImageCommand convert = getImageCommand(CommandType.convert);
            convert.run(op);
            System.out.println("缩放图片成功");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 压缩图片
     * @param srcImagePath 原图片地址
     * @param newImagePath 新图片地址
     * @param quality 压缩比例
     * 图片压缩比,有效值范围是0.0-100.0,数值越大,缩略图越清晰。
     * @return
     */
    public static boolean compressImage(String srcImagePath, String newImagePath, Double quality) {
        try {
            IMOperation op = new IMOperation();
            op.addImage(srcImagePath);
            op.quality(quality);
            op.addImage(newImagePath);
            ImageCommand convert = getImageCommand(CommandType.convert);
            convert.run(op);
            System.out.println("压缩图片成功");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 文字水印
     * @param srcImagePath 原图片地址
     * @param newImagePath 新图片地址
     * @param content 水印文字,不支持汉字
     * @return
     */
    public static boolean textImage(String srcImagePath, String newImagePath, String content) {
        try {
            IMOperation op = new IMOperation();
            op.addImage(srcImagePath);
            //右下角
            op.font("ArialBold").gravity("southeast").pointsize(60).fill("#F2F2F2").draw("text 10,10 " + content);
            op.addImage(newImagePath);
            ImageCommand convert = getImageCommand(CommandType.convert);
            convert.run(op);
            System.out.println("添加文字水印成功");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 图片水印
     * @param srcImagePath 原图片地址
     * @param newImagePath 新图片地址
     * @param appendImagePath 水印图片地址
     * @param dissolve 水印透明度,0-100
     * @return
     */
    public static boolean compositeImage(String srcImagePath, String newImagePath, String appendImagePath, Integer dissolve) {
        try {
            //原图片信息
            BufferedImage bufferedImage = ImageIO.read(new File(srcImagePath));
            int w = bufferedImage.getWidth();
            int h = bufferedImage.getHeight();
            //水印图片信息
            Image image = ImageIO.read(new File(appendImagePath));
            int w1 = image.getWidth(null);
            int h1 = image.getHeight(null);

            IMOperation op = new IMOperation();
            op.geometry(w1, h1, w-w1-10, h-h1-10);
            op.dissolve(dissolve);
            op.addImage(appendImagePath);
            op.addImage(srcImagePath);
            op.addImage(newImagePath);
            ImageCommand composite = getImageCommand(CommandType.composite);
            composite.run(op);
            System.out.println("添加图片水印成功");
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 获取图片信息
     * @param imagePath 图片地址
     * @return
     */
    public static Map<String, String> getImageInfo(String imagePath) {
        Map<String, String> imageInfo = new HashMap<>();
        try {
            IMOperation op = new IMOperation();
            op.format("%w,%h,%d/%f,%Q,%b,%e");
            op.addImage();
            ImageCommand identifyCmd = getImageCommand(CommandType.identify);//注意这里,用的是identify
            ArrayListOutputConsumer output = new ArrayListOutputConsumer();
            identifyCmd.setOutputConsumer(output);
            identifyCmd.run(op, imagePath);
            ArrayList<String> cmdOutput = output.getOutput();
            String[] result = cmdOutput.get(0).split(",");
            if (result.length == 6) {
                imageInfo.put("宽度", result[0]);
                imageInfo.put("高度", result[1]);
                imageInfo.put("路径", result[2]);
                imageInfo.put("质量", result[3]);
                imageInfo.put("大小", result[4]);
                imageInfo.put("格式", result[5]);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return imageInfo;
    }

}

测试

package imagemagick;

import java.util.Map;

public class Im4JavaTest {

    //源图片目录
    public static final String SRC_IMAGE_PATH = "C:\\Users\\Administrator\\Desktop\\test\\";
    //新图片目录
    public static final String NEW_IMAGE_PATH = "C:\\Users\\Administrator\\Desktop\\new\\";
    //水印图片地址
    public static final String APPEND_IMAGE_PATH = "C:\\Users\\Administrator\\Desktop\\test\\logo.jpg";

    public static void main(String[] args) {

        Im4JavaUtils.roateImage(SRC_IMAGE_PATH + "1.jpg", NEW_IMAGE_PATH + "1.jpg", 90.0);

        Im4JavaUtils.cutImage(SRC_IMAGE_PATH + "2.jpg", NEW_IMAGE_PATH + "2.jpg", 100, 100, 100, 100);

        Im4JavaUtils.zoomImage(SRC_IMAGE_PATH + "3.jpg", NEW_IMAGE_PATH + "3.jpg", 400, 270);

        Im4JavaUtils.compressImage(SRC_IMAGE_PATH + "4.jpg", NEW_IMAGE_PATH + "4.jpg", 50.0);

        Im4JavaUtils.textImage(SRC_IMAGE_PATH + "5.jpg", NEW_IMAGE_PATH + "5.jpg", "TEST");

        Im4JavaUtils.compositeImage(SRC_IMAGE_PATH + "6.jpg", NEW_IMAGE_PATH + "6.jpg", APPEND_IMAGE_PATH, 50);

        System.out.println("======获取图片信息=====");
        Map<String, String> imageInfo = Im4JavaUtils.getImageInfo(SRC_IMAGE_PATH + "6.jpg");
        for (String key : imageInfo.keySet()) {
            System.out.println(key + " : " + imageInfo.get(key));
        }
        System.out.println("======获取图片信息=====");

    }

}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ImageMagick 是一款强大的图像处理软件,通过它我们可以实现多张图片的合并。在 Java 中,我们可以通过调用 ImageMagick 的命令行工具来实现图片合并。 首先,我们需要确保系统中已经安装了 ImageMagick。可以在终端中输入 `magick -version` 命令来检查是否已经安装成功。 接下来,我们可以使用 Java 的 `Runtime` 类来执行 ImageMagick 的命令行工具。首先,我们需要构建一个字符串数组,其中包含我们要执行的命令。例如,如果我们想要合并两张图片A.jpg和B.jpg,那么我们可以构建如下的命令数组: ```java String[] command = {"magick", "convert", "A.jpg", "B.jpg", "+append", "output.jpg"}; ``` 这个命令数组中,`magick` 是 ImageMagick 的命令行工具,`convert` 是 ImageMagick 的功能之一,`A.jpg` 和 `B.jpg` 是要合并的两张图片的文件名,`+append` 是合并图片的参数,`output.jpg` 是合并后的图片的输出文件名。 接下来,我们可以使用 `Runtime` 类的 `exec` 方法来执行命令: ```java Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec(command); ``` 执行完毕后,我们可以通过 `process.waitFor()` 方法等待命令执行完成。 最后,我们可以通过 `ImageIO` 类将合并后的图片输出到本地文件中: ```java BufferedImage mergedImage = ImageIO.read(new File("output.jpg")); ImageIO.write(mergedImage, "jpg", new File("merged.jpg")); ``` 以上就是使用 ImageMagickJava 中合并图片的过程。需要注意的是,使用 ImageMagick 进行图片合并的同时也可以对图片进行其他处理,例如裁剪、缩放、旋转等。具体的命令和参数可以根据需求进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值