package com.document.handle.controller;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import com.document.tool.ImageMagickUtils;
import com.document.tool.SystemConfig;
@Controller
public class ImageAgentController {
private static final Logger LOG = LoggerFactory.getLogger(ImageAgentController.class);
/**
* ppt預(yù)覽圖片代理輸出
* @throws IOException
*/
@RequestMapping("/preview/images/{year}/{month}/{md5id}/{preview}/{filename}.{ext}")
public void cropImage(@PathVariable String year, @PathVariable String month, @PathVariable String md5id,
@PathVariable String preview, @PathVariable String filename, @PathVariable String ext,
HttpServletRequest request, HttpServletResponse response) throws IOException {
// String rootDir = "/data03/ovp/blobs/";
String rootDir = SystemConfig.getBlobDirectory();
String oname = filename.substring(1, filename.length());// 原圖文件名
String dirString = rootDir + year + "/" + month + "/" + md5id + "/" + oname + "." + ext;
String targetFileString = rootDir + year + "/" + month + "/" + md5id + "/preview/" + filename + "." + ext;
//如果原圖存在
File originImage = new File(oname);
if(originImage.exists()){
LOG.info("corpImage..." + dirString + " -> " + targetFileString);
File newfile = new File(targetFileString);
String pathString = newfile.getParent();
LOG.info("pathString...{} {}", pathString);
File pathFile = new File(pathString);
if (!pathFile.exists()) {
LOG.info("---create file---");
pathFile.mkdirs();
}
boolean status = ImageMagickUtils.scale(dirString, targetFileString, 240, 180);
if (status) {
response.reset();
response.setContentType("image/" + ext);
java.io.InputStream in = new java.io.FileInputStream(targetFileString);
// FilenameUrlUtils.getImageFilename(targetFileString);
if (in != null) {
byte[] b = new byte[1024];
int len;
while ((len = in.read(b)) != -1) {
response.getOutputStream().write(b);
}
in.close();
}
}
}else{
LOG.info("原圖目錄不存在-preview:{}",dirString);
}
}
/**
* ppt固定尺寸圖片代理輸出
* @throws IOException
* http://document.polyv.net/images/2016/03/de37d2ceb11ac068c18c5e4428541075/jpg-3/1000x540.png
*
* http://document.polyv.net/images/2016/03/de37d2ceb11ac068c18c5e4428541075/jpg-3.png
*/
@RequestMapping("/images/{year}/{month}/{md5id}/{filename}/{width}x{height}.{ext}")
public void cropfixedImage(@PathVariable String year, @PathVariable String month, @PathVariable String md5id,
@PathVariable String filename, @PathVariable Integer width, @PathVariable Integer height, @PathVariable String ext,
HttpServletRequest request, HttpServletResponse response) throws IOException {
// String rootDir = "/data03/ovp/blobs/";
String rootDir = SystemConfig.getBlobDirectory();
//String oname = filename.substring(1, filename.length());// 原圖文件名
String dirString = rootDir + year + "/" + month + "/" + md5id + "/" + ( filename + "." + ext);
String targetFileString = rootDir + year + "/" + month + "/" + md5id + "/" + filename + "/" + (width + "x" + height + "." + ext);
//如果原圖存在
File originImage = new File(dirString);
if(originImage.exists()){
File targetFileStringFile = new File(targetFileString);
if(!targetFileStringFile.exists()){
LOG.info("corpImage..." + dirString + " -> " + targetFileString);
File newfile = new File(targetFileString);
String pathString = newfile.getParent();
LOG.info("pathString...{} {}", pathString);
File pathFile = new File(pathString);
if (!pathFile.exists()) {
LOG.info("---create file---");
pathFile.mkdirs();
}
ImageMagickUtils.resizeWH(dirString, targetFileString,width,height);
}
response.setContentType("image/" + ext);
java.io.InputStream in = null;
try{
in = new java.io.FileInputStream(targetFileString);
response.setContentLength(in.available());
byte[] buffer = new byte[1024];
int count = 0;
while ((count = in.read(buffer)) > 0) {
response.getOutputStream().write(buffer, 0, count);
}
response.flushBuffer();
}catch(Exception e){
e.printStackTrace();
}finally {
try {
in.close();
} catch (Exception e) {
}
}
}else{
LOG.info("原圖目錄不存在:{}",dirString);
}
}
/**
* 圖片下載
*/
@RequestMapping("get/image/data")
public void downloadImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
String filePath = ServletRequestUtils.getStringParameter(request, "filePath", ""); //圖片訪問路勁
String fileName = ServletRequestUtils.getStringParameter(request, "fileName", ""); //名稱
if(StringUtils.isNotBlank(filePath) || StringUtils.isNotBlank(fileName)){
String destUrl = filePath;
//LOG.info("--------------"+filePath);
String fileFormat=filePath.substring(filePath.lastIndexOf("."));
//String name=fileName.trim()+fileFormat;
String name=filePath.substring(filePath.lastIndexOf("/")+1, filePath.length());
//File f = new File(filePath);
//response.setHeader("Content-Disposition", "attachment; filename="+java.net.URLEncoder.encode(f.getName(),"UTF-8"));
//LOG.info("--------------"+f.getName());
// 建立鏈接
URL url = new URL(destUrl);
HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();
// 連接指定的資源
httpUrl.connect();
// 獲取網(wǎng)絡(luò)輸入流
BufferedInputStream bis = new BufferedInputStream(httpUrl.getInputStream());
Integer lenf=httpUrl.getContentLength();
//String lenf=this.getFileLength(4189053, 7189053);
response.setContentType("application/x-msdownload");
response.setHeader("Content-Length", lenf.toString());//文件大小值5幾M
response.setHeader("Content-Disposition", "attachment; filename="+java.net.URLEncoder.encode(name,"UTF-8"));
OutputStream out = response.getOutputStream();
byte[] buf = new byte[1024];
if (destUrl != null) {
BufferedInputStream br = bis;
int len = 0;
while ((len = br.read(buf)) > 0){
out.write(buf, 0, len);
}
br.close();
}
out.flush();
out.close();
}
}
}
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對(duì)圖片文件進(jìn)行處理的工具類。
* @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);
/**
* 執(zhí)行圖片處理的命令。
* @param cmdLine 待執(zhí)行的命令
* @return exitValue,一般等于0時(shí)表示正常運(yùn)行結(jié)束
* @throws ExecuteException 命令執(zhí)行失敗時(shí)拋出此異常
* @throws IOException 當(dāng)發(fā)生IO錯(cuò)誤時(shí)拋出此異常
* @throws InterruptedException 當(dāng)?shù)却惒椒祷亟Y(jié)果被中斷時(shí)拋出此異常
*/
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 目標(biāo)圖片
* @param width 圖片圖片的寬度
* @param height 目標(biāo)圖片的高度
* @return 是否處理成功
*/
public static boolean scale(String src, String dst, int width, int height) {
// 構(gòu)建命令
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("縮略圖片時(shí)發(fā)生異常,Cause: ", e);
return false;
}
}
/**
* 按照高寬比例縮小圖片。
* @param src 源圖片
* @param dst 目標(biāo)圖片
* @param width 圖片圖片的寬度
* @param height 目標(biāo)圖片的高度
* @return 是否處理成功
*/
public static boolean thumbnail(String src, String dst, int width, int height) {
// 構(gòu)建命令
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("縮略圖片時(shí)發(fā)生異常,Cause: ", e);
return false;
}
}
/**
* 添加圖片水印。
* @param src 源圖片
* @param dst 目標(biāo)圖片
* @param logofile 水印圖片
* @param dissolve 和水印的融合度,0-100的數(shù)字
* @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) {
// 構(gòu)建命令
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("添加圖片水印時(shí)發(fā)生異常,Cause: ", e);
return false;
}
}
/**
* 添加圖片水印。
* @param src 源圖片
* @param dst 目標(biāo)圖片
* @param logofile 水印圖片
* @param dissolve 和水印的融合度,0-100的數(shù)字
* @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軸上水印圖片的左上頂點(diǎn)距離圖片左上角的距離
String _y = String.valueOf(height - y); // 在y軸上水印圖片的左上頂點(diǎn)距離圖片左上角的距離
// 構(gòu)建命令
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("添加圖片水印時(shí)發(fā)生異常,Cause: ", e);
return false;
}
}
/**
* 裁剪圖片。
* @param src 源圖片
* @param dst 目標(biāo)圖片
* @param width 目標(biāo)寬度
* @param height 目標(biāo)高度
* @param left 裁剪位置:距離左邊的像素
* @param top 裁剪位置:距離上邊的像素
* @return 是否處理成功
*/
public static boolean crop(String src, String dst, int width, int height, int left, int top) {
// 構(gòu)建命令
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("裁剪圖片時(shí)發(fā)生異常,Cause: ", e);
return false;
}
}
/**
* 獲取矩形的小圖。
* @param src 源圖片
* @param dst 目標(biāo)圖片
* @param width 目標(biāo)寬度
* @param height 目標(biāo)高度
* @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) { // 以寬為標(biāo)準(zhǔn)
s = getSize(origWidth, origHeight, width, height, 1);
} else {// 以高為標(biāo)準(zhǔn)
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 目標(biāo)圖片
* @param borderWidth 邊框的寬度
* @param borderHeight 邊框的高度
* @param borderColor 邊框的顏色
* @return 是否處理成功
*/
public static boolean border(String src, String dst, int borderWidth, int borderHeight, String borderColor) {
// 構(gòu)建命令
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("加圖片邊框時(shí)發(fā)生異常,Cause: ", e);
return false;
}
}
/**
* 轉(zhuǎn)換圖片格式。
* @param src 源圖片
* @param dst 目標(biāo)圖片
* @param format 轉(zhuǎn)換的格式
* @return 是否處理成功
*/
public static boolean format(String src, String dst, String format) {
// 構(gòu)建命令
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("轉(zhuǎn)換圖片格式時(shí)發(fā)生異常,Cause: ", e);
return false;
}
}
/**
* 轉(zhuǎn)換無限極的TIFF圖片。
*/
public static boolean convertTiff(String src, String dst) {
// 構(gòu)建命令
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("轉(zhuǎn)換圖片格式時(shí)發(fā)生異常,Cause: ", e);
return false;
}
}
/**
* 獲得要壓縮圖片的大小。
* @param w 圖片的原寬度
* @param h 圖片的原高度
* @param width 標(biāo)準(zhǔn)寬
* @param height 標(biāo)準(zhǔn)高
* @param type 類型 1-以寬為標(biāo)準(zhǔn)壓縮 2-以高為標(biāo)準(zhǔn)壓縮 3-以比例大小壓縮
* @return size[0]-要壓縮的寬度, size[1]-要壓縮的高度
*/
public static int[] getSize(double w, double h, double width, double height, int type) {
if (w < width) {// 如果原寬度比標(biāo)準(zhǔn)寬度小
width = w;
}
if (h < height) {// 如果原高度比標(biāo)準(zhǔn)高度小
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) {
// 構(gòu)建命令
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("縮略圖片時(shí)發(fā)生異常,Cause: ", e);
return false;
}
}
/**
* 指定寬度、高度。
* @param src
* @param width
* @param dst
*/
public static boolean resizeWH(String src,String dst, int width, int height ) {
// 構(gòu)建命令
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("縮略圖片時(shí)發(fā)生異常,Cause: ", e);
return false;
}
}
}