欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

利用Nginx 代理输出缩放图片

程序员文章站 2024-04-06 15:53:19
...
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.InputStreamin = 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.InputStreamin = 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();  
            // 获取网络输入流  
            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对图片文件进行处理的工具类。
 * @author XingNing OU
 */publicabstractclassImageMagickUtils {privatestaticfinal String EXECUTABLE_CONVERT = "/usr/bin/convert"; // convert命令privatestaticfinal String EXECUTABLE_COMPOSITE = "/usr/bin/composite"; // composite命令privatestaticfinallong EXECUTE_TIMEOUT = 30 * 60 * 1000L; // 30 minutesprivatestaticfinal Logger LOG = LoggerFactory.getLogger(ImageMagickUtils.class);

    /**
     * 执行图片处理的命令。
     * @param cmdLine 待执行的命令
     * @return exitValue,一般等于0时表示正常运行结束
     * @throws ExecuteException 命令执行失败时抛出此异常
     * @throws IOException 当发生IO错误时抛出此异常
     * @throws InterruptedException 当等待异步返回结果被中断时抛出此异常
     */publicstaticintexecuteCommandLine(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 是否处理成功
     */publicstaticbooleanscale(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);
            returntrue;
        } catch (Exception e) {
            LOG.error("缩略图片时发生异常,Cause: ", e);
            returnfalse;
        }
    }

    /**
     * 按照高宽比例缩小图片。
     * @param src 源图片
     * @param dst 目标图片
     * @param width 图片图片的宽度
     * @param height 目标图片的高度
     * @return 是否处理成功
     */publicstaticbooleanthumbnail(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);
            returntrue;
        } catch (Exception e) {
            LOG.error("缩略图片时发生异常,Cause: ", e);
            returnfalse;
        }
    }

    /**
     * 添加图片水印。
     * @param src 源图片
     * @param dst 目标图片
     * @param logofile 水印图片
     * @param dissolve 和水印的融合度,0-100的数字
     * @param gravity 叠放方向,East,West,North,South,NorthEast,NorthWest,SouthEast,SouthWest
     * @return 是否处理成功
     */publicstaticbooleandrawLogo(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);
            returntrue;
        } catch (Exception e) {
            LOG.error("添加图片水印时发生异常,Cause: ", e);
            returnfalse;
        }
    }

    /**
     * 添加图片水印。
     * @param src 源图片
     * @param dst 目标图片
     * @param logofile 水印图片
     * @param dissolve 和水印的融合度,0-100的数字
     * @param x 水印距离左下角的距离
     * @param y 水印距离右下角的距离
     * @return 是否处理成功
     */publicstaticbooleandrawLogo(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);
            returntrue;
        } catch (Exception e) {
            LOG.error("添加图片水印时发生异常,Cause: ", e);
            returnfalse;
        }
    }

    /**
     * 裁剪图片。
     * @param src 源图片
     * @param dst 目标图片
     * @param width 目标宽度
     * @param height 目标高度
     * @param left 裁剪位置:距离左边的像素
     * @param top 裁剪位置:距离上边的像素
     * @return 是否处理成功
     */publicstaticbooleancrop(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);
            returntrue;
        } catch (Exception e) {
            LOG.error("裁剪图片时发生异常,Cause: ", e);
            returnfalse;
        }
    }

    /**
     * 获取矩形的小图。
     * @param src 源图片
     * @param dst 目标图片
     * @param width 目标宽度
     * @param height 目标高度
     * @param left 裁剪位置:距离左边的像素
     * @param top 裁剪位置:距离上边的像素
     * @return 是否处理成功
     */publicstaticbooleancropRect(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 = newint[2];
        if (origWidth // 以宽为标准