江南才子 发表于 2021-8-11 11:20:44

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

本文实例为大家分享了Nginx代理输出缩放图片的具体代码,供大家参考,具体内容如下
nginx 配置文件:


# document ppt convert Configuration.
upstream document.polyv.net {
server 127.0.0.1:8080;
}

server {
listen 80;
server_name document.polyv.net;
index index.html index.htm;
charset utf-8;
client_max_body_size 1000m;

# ignore favicon.ico not exist.
location = /favicon.ico {
log_not_found off;
access_log off;
}

# not allow to visit hidden files.
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}

location / {
if ($request_filename ~* ^.*?\.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx)$) {
   add_header Content-Disposition: 'attachment;';
   add_header Content-Type: 'APPLICATION/OCTET-STREAM';
}

proxy_pass http://document.polyv.net;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REQUEST_HOST $host;

# include proxy.conf;
charset UTF-8;
}

# user upload files
location /images/ {
   #expires 7d;
alias /data03/ovp/blobs/;
   proxy_store on;
   proxy_store_access user:rw group:rw all:rw;
   proxy_set_header Accept-Encoding "";
   if ( !-f $request_filename ) {
    proxy_pass http://document.polyv.net;
   }
}

location /blobs/ {
   #expires 7d;
alias /data03/ovp/blobs/;
}

location /preview/images/ {
   #expires 7d;
   alias /data03/ovp/blobs/;
   proxy_store on;
   proxy_store_access user:rw group:rw all:rw;
   proxy_set_header Accept-Encoding "";
   if ( !-f $request_filename ) {
    proxy_pass http://document.polyv.net;
   }
}

}
代理输出缩放图片


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预览图片代理输出
* @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;
   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;
    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();
   // 获取网络输入流
   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;
   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对图片文件进行处理的工具类。
* @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;
if (origWidth < origHeight) { // 以宽为标准
   s = getSize(origWidth, origHeight, width, height, 1);
} else {// 以高为标准
   s = getSize(origWidth, origHeight, width, height, 2);
}

if (thumbnail(src, dst, s, s)) {
   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-要压缩的宽度, size-要压缩的高度
*/
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;
size = (int) width;
size = (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;
}
}
}
服务器上要安装imagemagick。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

文档来源:服务器之家http://www.zzvips.com/article/47228.html
页: [1]
查看完整版本: Nginx代理输出缩放图片的方法