Nginx代理输出缩放图片的方法

2019-10-17 16:35:30于丽

图片缩放的业务

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;
  }
 }
}