手把手教你整合Java+ImageMagick。
java 利用Img4JavaUtil 工具对图片做缩略图、裁剪等常用方法
-
安装ImageMagick最新版本, 并设置path系统环境变量。获取安装路径(用于设置java初始化ImageMagick)。
1)下载地址:http://www.imagemagick.org/script/download.php
2)选择版本:ImageMagick-7.0.8-33-Q16-x64-dll.exe
3)在安装过程中记得勾选Install legacy utilities(e.g. convert)选项。
4)添加到系统path环境变量:
5)打开命令行运行magick -help测试是否配置成功
6) JDK版本选择1.8
2.ImageMagick添加pom.xml的支持
im4java是一个封装DOM操作的类,用于java中拼接cmd命令代码 来实现图片裁剪的。
<dependency>
<groupId>org.im4java</groupId>
<artifactId>im4java</artifactId>
<version>1.4.0</version>
</dependency>
- 静态方法中初始化ImageMagick 。 只有windows环境下才需要,linux不需要。
设置全局的方法:
ProcessStarter.setGlobalSearchPath(“D:/Program Files/ImageMagick-7.0.8-Q16”);
4.献上我封装好的方法。(其中取中心化裁剪,和中心化缩略图最为好用!!!)
package com.bdxh.fileserver.utils;
import java.io.File;
import java.io.IOException;
import org.im4java.core.ConvertCmd;
import org.im4java.core.IM4JavaException;
import org.im4java.core.IMOperation;
import org.im4java.core.Info;
import org.im4java.core.InfoException;
import org.im4java.process.ProcessStarter;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;
public class Img4JavaUtil {
static {
//判断是否是windows系统
if(OSinfo.isWindows()) {
System.out.println("------------ START 初始化ImageMagickPath -------------");
ProcessStarter.setGlobalSearchPath("D:/Program Files/ImageMagick-7.0.8-Q16");
System.out.println("------------ END 初始化ImageMagickPath -------------");
}
}
/**
* 裁剪图片
* @param inImgPath 源图片地址
* @param outImgPath 目标图片地址
* @param width 宽
* @param height 高
* @param x 起点横坐标
* @param y 起点纵坐标
* @throws IOException
* @throws InterruptedException
* @throws IM4JavaException
*/
public static void cropImg(String inImgPath,String outImgPath,Integer width,Integer height,Integer x,Integer y) throws IOException, InterruptedException, IM4JavaException{
ConvertCmd cmd = new ConvertCmd();
IMOperation operation = new IMOperation();
operation.addImage(inImgPath);
//宽 高 起点横坐标 起点纵坐标
operation.crop(width, height, x, y);
operation.addImage(outImgPath);
cmd.run(operation);
}
/**
* 裁剪图片
* @param inImgPath 源图片地址
* @param outImgPath 目标图片地址
* @param width 宽
* @param height 高
* @param x 起点横坐标
* @param y 起点纵坐标
* @throws IOException
* @throws InterruptedException
* @throws IM4JavaException
*/
public void cropImg(String inImgPath,String outImgPath,Integer width,Integer height,Integer x,Integer y) throws IOException, InterruptedException, IM4JavaException{
ConvertCmd cmd = new ConvertCmd();
IMOperation operation = new IMOperation();
operation.addImage(inImgPath);
//宽 高 起点横坐标 起点纵坐标
operation.crop(width, height, x, y);
operation.addImage(outImgPath);
cmd.run(operation);
}
/**
* 裁剪中心化图片
* @param inImgPath 源图片地址
* @param outImgPath 目标图片地址
* @param width 宽
* @param height 高
* @throws IOException
* @throws InterruptedException
* @throws IM4JavaException
*/
public void cropCenterImg(String inImgPath,String outImgPath,Integer width,Integer height) throws IOException, InterruptedException, IM4JavaException{
ConvertCmd cmd = new ConvertCmd();
IMOperation operation = new IMOperation();
Info info = new Info(inImgPath);
Integer init_width = info.getImageWidth();
Integer init_height = info.getImageHeight();
// 如果裁剪的宽高都大于原始图片宽高 则先等比放大再裁剪
if(width>init_width || height>init_height){
// 等比放大
Integer temp_width = width;
if(init_height<init_width){
// 如果原图宽大于高 则以高为准放大
temp_width = null;
}
operation.resize(temp_width, height);
}
operation.addImage(inImgPath);
//宽 高 起点横坐标 起点纵坐标
operation.gravity("center");
operation.crop(width, height, 0, 0);
operation.addImage(outImgPath);
cmd.run(operation);
}
/**
* 得到图片的信息
* @throws InfoException
*/
public static String getImgInfo(String inImgPath) throws InfoException{
Info info = new Info(inImgPath);
System.out.println(info.getImageHeight());
System.out.println(info.getImageWidth());
return info.getImageWidth()+"x"+info.getImageHeight();
}
/**
* 等比缩放图片
* @param inImgPath
* @param outImgPath
* @param width 宽度不为空时 以宽度为准,为空时以高度为准(不能同时为空)
* @param height
* @throws IOException
* @throws InterruptedException
* @throws IM4JavaException
*/
public static void resizeImg(String inImgPath,String outImgPath,Integer width,Integer height) throws IOException, InterruptedException, IM4JavaException{
ConvertCmd cmd = new ConvertCmd();
IMOperation operation = new IMOperation();
operation.addImage(inImgPath);
//等比缩放图片
operation.resize(width, height);//高度为null则按宽度缩放
operation.addImage(outImgPath);
cmd.run(operation);
}
/**
* 等比缩放 (使用像素平均缩小)
* @param inImgPath
* @param outImgPath
* @param width
* @param height
* @throws IOException
* @throws InterruptedException
* @throws IM4JavaException
*/
public static void scaleImg(String inImgPath,String outImgPath,Integer width,Integer height) throws IOException, InterruptedException, IM4JavaException{
ConvertCmd cmd = new ConvertCmd();
IMOperation operation = new IMOperation();
operation.addImage(inImgPath);
//缩略图
operation.scale(width,height);
operation.addImage(outImgPath);
cmd.run(operation);
}
/**
* 把原图裁剪成正方形
* @param inImgPath
* @param operation
* @return
* @throws IM4JavaException
*/
public static IMOperation getCenterSquare(String inImgPath,IMOperation operation)throws IM4JavaException{
Info info = new Info(inImgPath);
Integer init_width = info.getImageWidth();
Integer init_height = info.getImageHeight();
if (init_width > init_height) {
init_width = init_height;
} else if (init_width < init_height) {
init_height = init_width;
}
operation.gravity("center");
operation.crop(init_width, init_height,0,0);
return operation;
}
/**
* 缩略图 (专门用于将非常大的图像缩小为小缩略图)
* @param inImgPath
* @param outImgPath
* @param width
* @param height
* @param editType = c 取中心化缩略图,否则取原等比缩略图
* @throws IOException
* @throws InterruptedException
* @throws IM4JavaException
*/
public void thumbnailImg(String inImgPath,String outImgPath,Integer width,Integer height,String editType) throws IOException, InterruptedException, IM4JavaException{
ConvertCmd cmd = new ConvertCmd();
IMOperation operation = new IMOperation();
operation.addImage(inImgPath);
//取中心化或者原图同比
if(editType!=null && editType.equals("c")) {
//分析宽高 先原图等比生成缩略图(缩略规则按原图大的一边为准取值)
Info info = new Info(inImgPath);
Integer init_width = info.getImageWidth();
Integer init_height = info.getImageHeight();
double width_v = (double)init_width/width;
double height_v = (double)init_height/height;
//原图是正方形
/*if(init_width == init_height){
operation.thumbnail(width,height);
//原图是宽大于高的长方形
}else */if(init_width >= init_height){
if (width_v >= height_v) {
operation.thumbnail(null,height);
} else if (width_v < height_v) {
operation.thumbnail(width,null);
}
//原图是高大于宽的长方形
}else if(init_width < init_height){if (width_v > height_v) {
operation.thumbnail(null,height);
} else if (width_v <= height_v) {
operation.thumbnail(width,null);
}
}
//再中心化截图
operation.gravity("center");
operation.crop(width, height,0,0);
}else{
operation.thumbnail(width,height);
}
operation.addImage(outImgPath);
cmd.run(operation);
}
/**
* 旋转图片
* @param inImgPath
* @param outImgPath
* @param x 旋转角度
* @throws IOException
* @throws InterruptedException
* @throws IM4JavaException
*/
public void rotateImg(String inImgPath,String outImgPath,Double x) throws IOException, InterruptedException, IM4JavaException{
ConvertCmd cmd = new ConvertCmd();
IMOperation operation = new IMOperation();
operation.addImage(inImgPath);
operation.rotate(x);
operation.addImage(outImgPath);
cmd.run(operation);
}
/**
* 缩略图 (原图画质缩略)
* @param inImgPath
* @param outImgPath
* @param width
* @param height
* @param editType
* @throws IOException
* @throws InterruptedException
* @throws IM4JavaException
*/
public void sampleImg(String inImgPath,String outImgPath,Integer width,Integer height,String editType) throws IOException, InterruptedException, IM4JavaException{
ConvertCmd cmd = new ConvertCmd();
IMOperation operation = new IMOperation();
operation.addImage(inImgPath);
//取中心化或者原图同比
if(editType!=null && editType.equals("center")) {
getCenterSquare(inImgPath,operation);
}
operation.sample(width,height);
// operation.quality(5.0); //设置生成图片质量
operation.addImage(outImgPath);
cmd.run(operation);
}
/**
* 将图片变成黑白图片
* @throws IOException
* @throws InterruptedException
* @throws IM4JavaException
*/
public void monochrome(String inImgPath,String outImgPath) throws IOException, InterruptedException, IM4JavaException{
ConvertCmd cmd = new ConvertCmd();
IMOperation operation = new IMOperation();
operation.addImage(inImgPath);
operation.monochrome();
operation.addImage(outImgPath);
cmd.run(operation);
}
/**
* 给图片加水印
* @param srcPath 源图片路径
*/
public static void addImgText(String inImgPath,String outImgPath,String str)throws IOException, InterruptedException, IM4JavaException{
IMOperation operation = new IMOperation();
operation.font("宋体").gravity("southeast").pointsize(18).fill("#BCBFC8")
.draw("text 5,5 "+str);
operation.encoding("UTF-8");
operation.addImage();
operation.addImage();
ConvertCmd convert = new ConvertCmd();
convert.run(operation, inImgPath,outImgPath);
}
/**
* 创建文件名称
* @param folder
* @param fileName
* @return
*/
public static File createFile(String folder, String fileName) {
File serverFile;
String suffix = getSuffix(fileName);
String destFileName = null;
long timeMillis = System.currentTimeMillis();
int i = 1;
do {
if (suffix.length() == 0) {
destFileName = String.format("%s_%d", timeMillis, i++);
} else {
destFileName = String.format("%s_%d.%s", timeMillis, i++, suffix);
}
serverFile = new File(folder, destFileName);
} while (serverFile.exists());
serverFile.getParentFile().mkdirs();
return serverFile;
}
/**
* 生成图片名称(根据旧的文件类型)
* @param rootPath 文件目录地址
* @param oldFileName 文件相对路径
* @param type 操作类型 c :中心化、o :原比例、自定义
* @return
*/
public String createFileName(String rootPath,String oldFileName,int width,int height,String type) {
// 初始化目录
String pathName = oldFileName.substring(0,oldFileName.lastIndexOf("/"));
String newFilePath = rootPath + pathName;
File dirFile = new File(newFilePath);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
// 生成文件名
String imgName =oldFileName.substring(oldFileName.lastIndexOf("/"));
String a = imgName.substring(0,imgName.lastIndexOf("."));
String b = imgName.substring(imgName.lastIndexOf("."));
return newFilePath + a + "_"+ width + "x"+ height +"_" + type + b;
}
/**
* 截取文件名称
* @param filePath
* @return
*/
public static String getSuffix(String filePath){
return filePath.substring(filePath.lastIndexOf("."));
}
/**
* main方法测试
* @param args
* @throws IOException
* @throws InterruptedException
* @throws IM4JavaException
*/
public static void main(String[] args) throws IOException, InterruptedException, IM4JavaException{
String inImgPath = "D:\\Documents\\Pictures\\1.jpg";
String outImgPath = "D:\\Documents\\Pictures\\2.jpg";
Img4JavaUtil test = new Img4JavaUtil();
// 中心化缩略图(常用)
test.thumbnailImg(inImgPath,outImgPath,400,400,"c");
// 裁剪图片
// test.cropImg(inImgPath,outImgPath+"裁剪-300x300.jpg",300,300,0,0);
// 获取图片信息
// test.getImgInfo(inImgPath);
// 等比缩放
// test.resizeImg(inImgPath,outImgPath+"等比缩放-w300.jpg",300,null);
// 旋转图片
// test.rotateImg(inImgPath,outImgPath+"旋转45.jpg",45.0);
// 转黑白图片
// test.monochrome(inImgPath,outImgPath+"转黑白.jpg");
// 加水印
// test.addImgText(inImgPath,outImgPath+"加水印.jpg","CCTV-100");
// 原图质量缩放
// test.scaleImg(inImgPath,outImgPath+"缩略图scale.jpg",100,null);
// 自动中心化裁剪
// test.cropCenterImg(inImgPath,outImgPath+"中心.jpg",400,300);
}
}
5.测试一波
原图:
做了400x400的中心化缩略图效果:
完美!