package com.document.tool;
import java.io.IOException;
import javax.swing.ImageIcon;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecuteResultHandler;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.ExecuteWatchdog;
import org.apache.commons.exec.Executor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 使用ImageMagick对图片文件进行处理的工具类。
* @author XingNing OU
*/
public abstract class ImageMagickUtils {
private static final String EXECUTABLE_CONVERT = “/usr/bin/convert”; // convert命令
private static final String EXECUTABLE_COMPOSITE = “/usr/bin/composite”; // composite命令
private static final long EXECUTE_TIMEOUT = 30 * 60 * 1000L; // 30 minutes
private static final Logger LOG = LoggerFactory.getLogger(ImageMagickUtils.class);
/**
* 执行图片处理的命令。
* @param cmdLine 待执行的命令
* @return exitValue,一般等于0时表示正常运行结束
* @throws ExecuteException 命令执行失败时抛出此异常
* @throws IOException 当发生IO错误时抛出此异常
* @throws InterruptedException 当等待异步返回结果被中断时抛出此异常
*/
public static int executeCommandLine(CommandLine cmdLine) throws ExecuteException, IOException,
InterruptedException {
Executor executor = new DefaultExecutor();
executor.setExitValue(0);
// Kill a run-away process after EXECUTE_TIME milliseconds.
ExecuteWatchdog watchdog = new ExecuteWatchdog(EXECUTE_TIMEOUT);
executor.setWatchdog(watchdog);
// Execute the print job asynchronously.
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
executor.execute(cmdLine, resultHandler);
// Some time later the result handler callback was invoked.
resultHandler.waitFor();
// So we can safely request the exit value.
return resultHandler.getExitValue();
}
/**
* 按照高宽比例缩小图片。
* @param src 源图片
* @param dst 目标图片
* @param width 图片图片的宽度
* @param height 目标图片的高度
* @return 是否处理成功
*/
public static boolean scale(String src, String dst, int width, int height) {
// 构建命令
CommandLine cmdLine = new CommandLine(EXECUTABLE_CONVERT);
cmdLine.addArgument(src);
cmdLine.addArgument(“-scale”);
cmdLine.addArgument(width + “x” + height);
cmdLine.addArgument(dst);
try {
executeCommandLine(cmdLine);
return true;
} catch (Exception e) {
LOG.error(“缩略图片时发生异常,Cause: “, e);
return false;
}
}
/**
* 按照高宽比例缩小图片。
* @param src 源图片
* @param dst 目标图片
* @param width 图片图片的宽度
* @param height 目标图片的高度
* @return 是否处理成功
*/
public static boolean thumbnail(String src, String dst, int width, int height) {
// 构建命令
CommandLine cmdLine = new CommandLine(EXECUTABLE_CONVERT);
cmdLine.addArgument(src);
cmdLine.addArgument(“-thumbnail”);
cmdLine.addArgument(width + “x” + height);
cmdLine.addArgument(dst);
try {
executeCommandLine(cmdLine);
return true;
} catch (Exception e) {
LOG.error(“缩略图片时发生异常,Cause: “, e);
return false;
}
}
/**
* 添加图片水印。
* @param src 源图片
* @param dst 目标图片
* @param logofile 水印图片
* @param dissolve 和水印的融合度,0-100的数字
* @param gravity 叠放方向,East,West,North,South,NorthEast,NorthWest,SouthEast,SouthWest
* @return 是否处理成功
*/
public static boolean drawLogo(String src, String dst, String logofile, int dissolve, String gravity) {
// 构建命令
CommandLine cmdLine = new CommandLine(EXECUTABLE_COMPOSITE);
cmdLine.addArgument(“-dissolve”);
cmdLine.addArgument(dissolve + “%”);
cmdLine.addArgument(“-gravity”);
cmdLine.addArgument(gravity);
cmdLine.addArgument(logofile);
cmdLine.addArgument(src);
cmdLine.addArgument(dst);
try {
executeCommandLine(cmdLine);
return true;
} catch (Exception e) {
LOG.error(“添加图片水印时发生异常,Cause: “, e);
return false;
}
}
/**
* 添加图片水印。
* @param src 源图片
* @param dst 目标图片
* @param logofile 水印图片
* @param dissolve 和水印的融合度,0-100的数字
* @param x 水印距离左下角的距离
* @param y 水印距离右下角的距离
* @return 是否处理成功
*/
public static boolean drawLogo(String src, String dst, String logofile, int dissolve, int x, int y) {
ImageIcon icon = new ImageIcon(src);
int width = icon.getIconWidth(); // 源图的宽
int height = icon.getIconHeight(); // 源图的高
String _x = String.valueOf(width – x); // 在x轴上水印图片的左上顶点距离图片左上角的距离
String _y = String.valueOf(height – y); // 在y轴上水印图片的左上顶点距离图片左上角的距离
// 构建命令
CommandLine cmdLine = new CommandLine(EXECUTABLE_COMPOSITE);
cmdLine.addArgument(“-dissolve”);
cmdLine.addArgument(dissolve + “%”);
cmdLine.addArgument(“-geometry”);
cmdLine.addArgument(_x + “+” + _y);
cmdLine.addArgument(logofile);
cmdLine.addArgument(src);
cmdLine.addArgument(dst);
try {
executeCommandLine(cmdLine);
return true;
} catch (Exception e) {
LOG.error(“添加图片水印时发生异常,Cause: “, e);
return false;
}
}
/**
* 裁剪图片。
* @param src 源图片
* @param dst 目标图片
* @param width 目标宽度
* @param height 目标高度
* @param left 裁剪位置:距离左边的像素
* @param top 裁剪位置:距离上边的像素
* @return 是否处理成功
*/
public static boolean crop(String src, String dst, int width, int height, int left, int top) {
// 构建命令
CommandLine cmdLine = new CommandLine(EXECUTABLE_CONVERT);
cmdLine.addArgument(src);
cmdLine.addArgument(“-crop”);
cmdLine.addArgument(width + “x” + height + “+” + left + “+” + top);
cmdLine.addArgument(dst);
try {
executeCommandLine(cmdLine);
return true;
} catch (Exception e) {
LOG.error(“裁剪图片时发生异常,Cause: “, e);
return false;
}
}
/**
* 获取矩形的小图。
* @param src 源图片
* @param dst 目标图片
* @param width 目标宽度
* @param height 目标高度
* @param left 裁剪位置:距离左边的像素
* @param top 裁剪位置:距离上边的像素
* @return 是否处理成功
*/
public static boolean cropRect(String src, String dst, int width, int height, int left, int top) {
ImageIcon icon = new ImageIcon(src);
int origWidth = icon.getIconWidth();
int origHeight = icon.getIconHeight();
int[] s = new int[2];
if (origWidth < origHeight) { // 以宽为标准
s = getSize(origWidth, origHeight, width, height, 1);
} else {// 以高为标准
s = getSize(origWidth, origHeight, width, height, 2);
}
if (thumbnail(src, dst, s[0], s[1])) {
return crop(src, dst, width, height, left, top);
}
return false;
}
/**
* 加边框。
* @param src 源图片
* @param dst 目标图片
* @param borderWidth 边框的宽度
* @param borderHeight 边框的高度
* @param borderColor 边框的颜色
* @return 是否处理成功
*/
public static boolean border(String src, String dst, int borderWidth, int borderHeight, String borderColor) {
// 构建命令
CommandLine cmdLine = new CommandLine(EXECUTABLE_CONVERT);
cmdLine.addArgument(“-bordercolor”);
cmdLine.addArgument(borderColor);
cmdLine.addArgument(“-border”);
cmdLine.addArgument(borderWidth + “x” + borderHeight);
cmdLine.addArgument(src);
cmdLine.addArgument(dst);
try {
executeCommandLine(cmdLine);
return true;
} catch (Exception e) {
LOG.error(“加图片边框时发生异常,Cause: “, e);
return false;
}
}
/**
* 转换图片格式。
* @param src 源图片
* @param dst 目标图片
* @param format 转换的格式
* @return 是否处理成功
*/
public static boolean format(String src, String dst, String format) {
// 构建命令
CommandLine cmdLine = new CommandLine(EXECUTABLE_CONVERT);
cmdLine.addArgument(src);
cmdLine.addArgument(“-format”);
cmdLine.addArgument(“” + format + “”);
cmdLine.addArgument(dst);
try {
executeCommandLine(cmdLine);
return true;
} catch (Exception e) {
LOG.error(“转换图片格式时发生异常,Cause: “, e);
return false;
}
}
/**
* 转换无限极的TIFF图片。
*/
public static boolean convertTiff(String src, String dst) {
// 构建命令
CommandLine cmdLine = new CommandLine(EXECUTABLE_CONVERT);
cmdLine.addArgument(src);
cmdLine.addArgument(“-colorspace”);
cmdLine.addArgument(“RGB”);
cmdLine.addArgument(dst);
try {
executeCommandLine(cmdLine);
return true;
} catch (Exception e) {
LOG.error(“转换图片格式时发生异常,Cause: “, e);
return false;
}
}
/**
* 获得要压缩图片的大小。
* @param w 图片的原宽度
* @param h 图片的原高度
* @param width 标准宽
* @param height 标准高
* @param type 类型 1-以宽为标准压缩 2-以高为标准压缩 3-以比例大小压缩
* @return size[0]-要压缩的宽度, size[1]-要压缩的高度
*/
public static int[] getSize(double w, double h, double width, double height, int type) {
if (w < width) {// 如果原宽度比标准宽度小
width = w;
}
if (h < height) {// 如果原高度比标准高度小
height = h;
}
double scale = w / h;
switch (type) {
case 1:
height = width / scale;
break;
case 2:
width = height * scale;
break;
case 3:
if (width / height > scale) {
width = height * scale;
} else if ((width / height) < scale) {
height = width / scale;
}
break;
}
int[] size = new int[2];
size[0] = (int) width;
size[1] = (int) height;
return size;
}
/**
* 指定宽度。
* @param src
* @param width
* @param dst
*/
public static boolean resize(String src, int width, String dst) {
// 构建命令
CommandLine cmdLine = new CommandLine(EXECUTABLE_CONVERT);
cmdLine.addArgument(src);
cmdLine.addArgument(“-resize”);
cmdLine.addArgument(width + “”);
cmdLine.addArgument(dst);
try {
executeCommandLine(cmdLine);
return true;
} catch (Exception e) {
LOG.error(“缩略图片时发生异常,Cause: “, e);
return false;
}
}
/**
* 指定宽度、高度。
* @param src
* @param width
* @param dst
*/
public static boolean resizeWH(String src,String dst, int width, int height ) {
// 构建命令
CommandLine cmdLine = new CommandLine(EXECUTABLE_CONVERT);
cmdLine.addArgument(src);
cmdLine.addArgument(“-resize”);
cmdLine.addArgument(width + “x” + height +”!”);
cmdLine.addArgument(dst);
try {
executeCommandLine(cmdLine);
return true;
} catch (Exception e) {
LOG.error(“缩略图片时发生异常,Cause: “, e);
return false;
}
}
}