访问图片支持自定义长宽大小

实现原理:
在原有的图片上去生成多一份数据变化后的图。其实像七牛这样的加载也是可以按照这个原理进行实现。
1、配置访问的路径。服务器资源放于本地路径
project.path = /home/images/
basePath = /uploadFile/

/**
 * 标注此文件为一个配置项,spring boot才会扫描到该配置。该注解类似于之前使用xml进行配置
 */
@Configuration
public class WebMvcConfigurerAdapter extends org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter {


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        ValueConfig valueConfig = SpringContextHolder.getBean("valueConfig");
        registry.addResourceHandler("/uploadFile/**").addResourceLocations("file:"+valueConfig.getProjectPath()+valueConfig.getBasePath());
        super.addResourceHandlers(registry);
    }
}

 

配置拦截器,以便每次请求需要转换的资源进行转换

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.FilterConfig;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class ImagesFilter implements Filter {
    private static Logger log = LoggerFactory.getLogger(ImagesFilter.class);

    private String basePath = "/uploadFile/";
    private static List<String> suffixMap = null;


    static {
        suffixMap = Lists.newArrayList();
        suffixMap.add("jpg");
        suffixMap.add("png");
        suffixMap.add("jpeg");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String w = request.getParameter("w");
        String h = request.getParameter("h");
        String uri = httpRequest.getRequestURI();
        String suffx = uri.substring(uri.lastIndexOf(".") + 1);

        //log.info("w:" + w);
        //log.info("h:" + h);
        //log.info("uri:" + uri);
        //log.info("suffx:" + suffx);
        try {
            if (StringUtils.isNumeric(w) && StringUtils.isNumeric(h) && suffixMap.contains(suffx.toLowerCase())) {
                if (uri.contains("_thumbs_auto")) {
                    chain.doFilter(request, response);
                    return;
                }
                ValueConfig valueConfig = SpringContextHolder.getBean("valueConfig");
                String newuri = "/uploadFile/_thumbs_auto/" + uri.substring(0, uri.lastIndexOf(".")).replaceFirst(basePath, "") + "_" + w + "x" + h + "." + suffx;
                String filename = valueConfig.getProjectPath() + newuri;
                //log.info("filename:" + filename);
                File file = new File(filename);
                boolean b = false;
                if (!file.exists()) {
                    String newPath = file.getParent();
                    File p = new File(newPath);
                    if (!p.exists()) {
                        p.mkdirs();
                    }
                    //log.info("newPath:" + newPath);
                    b = thumbnailImage(new File(valueConfig.getProjectPath() + java.net.URLDecoder.decode(uri, "UTF-8")), Integer.parseInt(w), Integer.parseInt(h), filename, false);
                } else {
                    b = true;
                }
                //log.info("b:" + b);
                if (b) {
                    httpRequest.getRequestDispatcher(newuri).forward(httpRequest, response);
                }
            } else {
                chain.doFilter(request, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void destroy() {

    }

    @Override
    public void init(FilterConfig config) throws ServletException {
    }

    /**
     * <p>
     * Title: thumbnailImage
     * </p>
     * <p>
     * Description: 根据图片路径生成缩略图
     * </p>
     *
     * @param imgFile  原图片路径
     * @param w        缩略图宽
     * @param h        缩略图高
     * @param filename 生成缩略图的文件名
     * @param force    是否强制按照宽高生成缩略图(如果为false,则生成最佳比例缩略图)
     */
    public static boolean thumbnailImage(File imgFile, int w, int h, String filename, boolean force) {
        if (imgFile.exists()) {
            try {
                // ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG,
                // JPEG, WBMP, GIF, gif]
                String types = Arrays.toString(ImageIO.getReaderFormatNames());
                String suffix = null;
                // 获取图片后缀
                if (imgFile.getName().indexOf(".") > -1) {
                    suffix = imgFile.getName().substring(imgFile.getName().lastIndexOf(".") + 1);
                }// 类型和图片后缀全部小写,然后判断后缀是否合法
                if (suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase()) < 0) {
                    log.error("Sorry, the image suffix is illegal. the standard image suffix is {}." + types);
                    return false;
                }
                log.debug("target image's size, width:{}, height:{}.", w, h);
                Image img = ImageIO.read(imgFile);
                int newWidth;
                int newHeight;
                BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
                Graphics g = bi.getGraphics();
                if (!force) {
                    int imgWidth = img.getWidth(null);
                    int imgHeight = img.getHeight(null);
                    // 根据原图与要求的缩略图比例,找到最合适的缩略图比例
                    double rate1 = ((double) imgWidth) / (double) w;
                    double rate2 = ((double) imgHeight) / (double) h;

                    // 根据缩放比率大的进行缩放控制
                    double rate = rate1 < rate2 ? rate1 : rate2;
                    newWidth = (int) ((double) imgWidth / rate);
                    newHeight = (int) ((double) imgHeight / rate);
                    if (rate1 < rate2) {
                        g.drawImage(img, 0, (0 - newHeight / 2 + (h / 2)), newWidth, newHeight, Color.LIGHT_GRAY, null);
                    } else {
                        g.drawImage(img, (0 - newWidth / 2 + (w / 2)), 0, newWidth, newHeight, Color.LIGHT_GRAY, null);
                    }
                } else {
                    g.drawImage(img, 0, 0, w, h, Color.LIGHT_GRAY, null);
                }
                g.dispose();
                ImageIO.write(bi, suffix, new File(filename));
                return true;
            } catch (IOException e) {
                log.error("generate thumbnail image failed.", e);
            }
        } else {
            log.warn("the image is not exist. path:" + imgFile.getPath() + imgFile.getName());
        }
        return false;
    }
}

 

 

最终的实现效果:

url/uploadFile/20190513/146050e3-2f57-4a3e-89cb-75fa89653f21.jpg?w=100&h=100

 url/uploadFile/20190513/146050e3-2f57-4a3e-89cb-75fa89653f21.jpg

 

posted @ 2019-07-09 15:14  jimw  阅读(413)  评论(0编辑  收藏  举报