H5学习之路-图片旋转、压缩处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qiyongkang520/article/details/54897014

最近一直在网上找关于图片上传、旋转处理、压缩处理等相关的资料,发现也不是很多。首先图片处理还是挺复杂的,完全靠自己写代码实现,笔者感觉自己不具备这个实力,所以还是在网上找一些好的插件,然后综合下,节省时间。
记得在上一篇博文就介绍了图片上传的方案,今天就来说说图片旋转和压缩处理。因为这两点还是挺重要的,之所以会处理旋转这个问题,是由于ios拍照存在这个bug,导致上传的图片方向逆时针旋转了90。那么,怎么解决呢?其实,上篇博文所使用的两个前端插件都解决了旋转的问题,所以这个就不用担心了,虽然在后台也可以处理,但是还是比较麻烦的,大家可以去研究下。压缩的话,由于图片太大了,不压缩使用,会导致加载图片太慢。那么是在后台处理,还是前端处理呢?这一点我也不太清楚,需要结合性能和兼容性去选择。由于thumbnailator这个后台插件封装了对图片相关的处理,所以笔者就选用这个插件了,比较方便,下面笔者就来进行介绍。

一、maven依赖

<!-- 图片处理插件 -->
    <dependency>
      <groupId>net.coobird</groupId>
      <artifactId>thumbnailator</artifactId>
      <version>0.4.8</version>
    </dependency>

    <!-- 图片EXIF信息 -->
    <dependency>
      <groupId>com.drewnoakes</groupId>
      <artifactId>metadata-extractor</artifactId>
      <version>2.6.2</version>
    </dependency>

压缩处理

笔者把代码封装到了一个工具类中,如下:

package com.qiyongkang.sys.util;

import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;

import net.coobird.thumbnailator.Thumbnails;

/**
 * 
 * ClassName: ImageUtil <br/>
 * Function: 图片处理. <br/>
 * date: 2017年2月6日 下午1:49:15 <br/>
 *
 * @author qiyongkang
 * @version 
 * @since JDK 1.6
 */
public class ImageUtil {
    private static Logger logger = LogManager.getLogger(ImageUtil.class);

    //宽
    public static int IMAGE_WIDTH = 1;

    //高
    public static int IMAGE_HEIGHT = 2;

    //方向
    public static int ORIENTATION_ONE = 1;  //正常
    public static int ORIENTATION_THREE = 3;  //180
    public static int ORIENTATION_SIX = 6;  //顺时针90
    public static int ORIENTATION_EIGHT = 8;  //逆时针90,顺时针270

    /**
     * 
     * getImageSize: 获取图片大小. <br/>
     *
     * @author qiyongkang
     * @return
     * @since JDK 1.6
     */
    public static int getImageSize(File file, int flag) {
        int size = 0;

        if (file == null || !file.exists()) 
            return size;
        try {
            if (IMAGE_WIDTH == flag) {
                size = ImageIO.read(file).getWidth();
            } else if (IMAGE_HEIGHT == flag) {
                size = ImageIO.read(file).getHeight();
            }
        } catch (IOException e) {
            logger.error("获取图片的大小异常", e);
            e.printStackTrace();
        }
        return size;
    }

    /**
     * 
     * getImageOrientation: 获取图片的方向 <br/>
     *
     * @author qiyongkang
     * @param file
     * @return
     * @since JDK 1.6
     */
    public static int getImageOrientation(File file) {
        int orientation = ORIENTATION_ONE;
        try {
            Metadata metadata = ImageMetadataReader.readMetadata(file);
            Directory dr = metadata.getDirectory(ExifIFD0Directory.class);
            if (dr == null) {
                logger.info("没有方向信息");
                return orientation;
            }

            orientation = dr.getInt(ExifIFD0Directory.TAG_ORIENTATION);
            logger.info("orientation:" + orientation);
        } catch (Exception e) {
            logger.error("获取图片的方向异常", e);
            e.printStackTrace();
        }
        return orientation;
    }

    /**
     * 
     * rotateImage: 旋转图片到正常的方向. <br/>
     *
     * @author qiyongkang
     * @since JDK 1.6
     */
    public static void rotateImage(File file) {
        //计算方向
        int orientation = getImageOrientation(file);

        double angle = 0d;
        if (orientation > ORIENTATION_ONE) {
            //进行图片处理
            switch (orientation) {
            case 3:
                //需要旋转180度
                angle = 180d;
                break;
            case 6:
                //需要旋转270度
                angle = 270d;
                break;
            case 8:
                //需要旋转90度
                angle = 90d;
                break;
            }
        }
        try {
            Thumbnails.of(file).scale(1).rotate(angle).toFile(file);;
        } catch (IOException e) {
            logger.error("旋转图片异常", e);
            e.printStackTrace();
        }
    }

    /**
     * 
     * impressImage: 压缩图片. <br/>
     *
     * @author qiyongkang
     * @param file
     * @param width
     * @param height
     * @since JDK 1.6
     */
    public static void impressImage(File file, int width, int height) {
        try {
            Thumbnails.of(file).size(width, height).toFile(file);
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("压缩图片异常:" + e);
        }
    }

    public static void main(String[] args) {
        File file = new File("C:\\Users\\qiyongkang\\Desktop\\测试图片\\17251486371832020.jpg");
//        rotateImage(file);
        System.out.println("图片的方向:" + getImageOrientation(file));
    }
}

使用例子

在上一篇博文已经贴出了上传的代码,这里就是加了点压缩处理的代码,如下:

/**
 * Project Name:qyk_testSpringMVC
 * File Name:FileController.java
 * Package Name:com.qiyongkang.sys.controller
 * Date:2016年11月6日下午3:12:05
 * Copyright (c) 2016, Thinkive(http://www.thinkive.com/) All Rights Reserved.
 *
*/

package com.qiyongkang.sys.controller;

import java.io.File;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.qiyongkang.sys.dto.ExtJsObject;
import com.qiyongkang.sys.util.ImageUtil;

/**
 * ClassName:FileController <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date: 2016年11月6日 下午3:12:05 <br/>
 * 
 * @author qiyongkang
 * @version
 * @since JDK 1.6
 * @see
 */
@Controller
@RequestMapping
public class FileController {
    /**
     * 日志类
     */
    private static Logger log = LogManager.getLogger(FileController.class);

    private String tempPath = "/uploadImageTemp";// 临时存储目录

    private String savePath = "/userImage";// 存储目录

    private String fileName = ""; // 文件名

    private static int PICTURE_WIDTH = 100; //压缩成的宽度

    @RequestMapping
    @ResponseBody
    public ExtJsObject uploadImage(HttpServletRequest request) {
        ExtJsObject extJsObject = new ExtJsObject();
        try {
            // 获取临时目录
            String tempPathDir = request.getSession().getServletContext().getRealPath(this.tempPath);
            File tempPathDirFile = new File(tempPathDir);
            if (!tempPathDirFile.exists()) {
                tempPathDirFile.mkdirs();
            }

            // 存储目录
            String realDir = request.getSession().getServletContext().getRealPath(this.savePath);
            File realDirFile = new File(realDir);
            if (!realDirFile.exists()) {
                realDirFile.mkdirs();
            }

            // Create a factory for disk-based file items
            DiskFileItemFactory factory = new DiskFileItemFactory();

            // Set factory constraints
            factory.setSizeThreshold(4096); // 设置缓冲区大小,这里是4kb
            factory.setRepository(tempPathDirFile);// 设置缓冲区目录

            // Create a new file upload handler
            ServletFileUpload upload = new ServletFileUpload(factory);

            // Set overall request size constraint
            upload.setSizeMax(4194304); // 设置最大文件尺寸,这里是4MB

            List<FileItem> items = upload.parseRequest(request);// 得到所有的文件
            Iterator<FileItem> i = items.iterator();
            while (i.hasNext()) {
                FileItem fi = (FileItem) i.next();
                String fileName = fi.getName();
                if (fileName != null) {
                    // 这里加一个限制,如果不是图片格式,则提示错误. (gif,jpg,jpeg,bmp,png)
                    String suffixName = FilenameUtils.getExtension(fileName);
                    if ("gif".equalsIgnoreCase(suffixName) || "jpg".equalsIgnoreCase(suffixName)
                            || "jpeg".equalsIgnoreCase(suffixName) || "bmp".equalsIgnoreCase(suffixName)
                            || "png".equalsIgnoreCase(suffixName)) {
                        // 文件名
                        this.fileName = new Date().getTime() + "." + FilenameUtils.getExtension(fileName);
                        File savedFile = new File(realDir, this.fileName);
                        fi.write(savedFile);

                        // 小图片
                        File savedSmallFile = new File(realDir + "/small/", this.fileName);
                        FileUtils.copyFile(savedFile, savedSmallFile);
                        //压缩一把
                        ImageUtil.impressImage(savedSmallFile, PICTURE_WIDTH, PICTURE_WIDTH);

                    } else {
                        extJsObject.setSuccess(false);
                        extJsObject.setMsg("非图片格式,请重新上传!");
                    }
                }
            }

            extJsObject.setSuccess(true);
            extJsObject.setMsg("上传成功!");
            extJsObject.setResult(this.fileName);
        } catch (Exception e) {
            extJsObject.setSuccess(false);
            extJsObject.setMsg("上传失败!");
            log.error("图片上传失败", e);
        }
        return extJsObject;
    }
}

好了,就介绍到这了,用起来还是比较简单的,大家可以去试试,同时也欢迎分享更好的方式!

猜你喜欢

转载自blog.csdn.net/qiyongkang520/article/details/54897014