Java实现等比例缩略图

1.简介:Web应用为上传图片生成缩略图是常见的基本功能,通过缩略图生成提高了信息浏览时的性能,在保证用户使用体验的同时减少了数据传输量。

2.实现图片等比例缩略图生成,方式及相关工具介绍:

  (1)Thumbnailator类库(推荐)

       工具:size()API方法

  (2)Java AWT类库(复杂)

  根据缩略比例计算缩略图高度贺宽度,使用Image类获得原图的缩放版本,使用ImageIO类保存缩略图;

    工具:bufferedImage(图像的存储和操作);ImageIO(图片读入、输出、生成);Graphics(图片的绘制)。

  本实例是基于springMVC框架的Java web应用程序,允许上传图片,并生成图片的缩略图。

3.实现步骤

  (1)应用程序框架搭建;

  (2)上传文件界面的开发;

  (3)控制器开发;

  (4)编写图片上传服务类;

  (5编写缩略图生成服务类

  需要的关键压缩使用的jar包:

  搭建web项目目录:

直接上核心代码:

  控制层controller实现:

@Controller
@RequestMapping("/")
public class ThumbnailController {
    @Autowired
    private UploadService uploadService;
    @Autowired
    private ThumbnailService thumbnailService;
    @RequestMapping(value="/thumbnail",method=RequestMethod.POST)
    public ModelAndView thumbnail(@RequestParam("image") CommonsMultipartFile file,HttpSession session) throws Exception{
        System.out.println("=========================");
        //主要针对于图片上传
        //相对路径
        String uploadPath="/images";
        //图片在服务器上的绝对路径信息
        String realUploadPath=session.getServletContext().getRealPath(uploadPath);
        //返回的结果
        //图片原图在服务器上访问的相对路径信息
        String imageUrl=uploadService.uploadImage(file, uploadPath, realUploadPath);
        //缩略图访问路径
        String thumImageUrl=thumbnailService.thumbnail(file, uploadPath, realUploadPath);
        //设置返回前端显示(渲染)
        ModelAndView modelAndView=new ModelAndView();
        modelAndView.addObject("imageURL", imageUrl);
        modelAndView.addObject("thumImageURL", thumImageUrl);
        
        modelAndView.setViewName("thumbnail");
        return modelAndView;
    }
}

  文件上传的业务实现类,代码(service):

/**
 * 文件上传文件的处理
 */
@Service
public class UploadService {
    public String uploadImage(CommonsMultipartFile file,String uploadPath,String realUploadPath){
        InputStream iStream=null;
        OutputStream oStream=null;
        try {
            //获取上传文件的流文件
            iStream=file.getInputStream();
            //创建文件输出流与位置
            String des=realUploadPath+"/"+file.getOriginalFilename();
            oStream=new FileOutputStream(des);
            byte[] buffer=new byte[1024];
            while (iStream.read(buffer)>0) {
                oStream.write(buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(iStream!=null){
                try {
                    iStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(oStream!=null){
                try {
                    oStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //返回文件上传的相对路径
        return uploadPath+"/"+file.getOriginalFilename();
    }
}

图片缩略处理,实现方式:

  (1)Thumbnails图片缩略处理,代码如下:

/**
 * Thumbnails图片缩略处理
 */
@Service
public class ThumbnailService {
    public static final int WIDTH=100;
    public static final int HEIGHT=100;
    public String thumbnail(CommonsMultipartFile file,String uploadPath,String realUploadPath){
        try {
            String des=realUploadPath+"/thum_"+file.getOriginalFilename();
            //图片缩略图实现,强制按照指定的宽高进行缩略keepAspectRatio(false)
//方式一
// Thumbnails.of(file.getInputStream()).size(WIDTH, HEIGHT).toFile(des); //方式二
       Builder<? extends InputStream> thumbnail = Thumbnails.of(file.getInputStream()); thumbnail.size(WIDTH, HEIGHT); thumbnail.toFile(des); } catch (Exception e) { e.printStackTrace(); } //缩略图返回的相对路径 return uploadPath+"/thum_"+file.getOriginalFilename(); } }

  (2)AWT图片缩略处理,代码如下:

/**
 * AWT图片缩略处理
 */
@Service
public class AWTService {
    public static final int WIDTH=100;
    public static final int HEIGHT=100;
    public String thumbnail(CommonsMultipartFile file,String uploadPath,String realUploadPath){
        OutputStream oStream=null;
        try {
            String des=realUploadPath+"/thum_"+file.getOriginalFilename();
            oStream=new FileOutputStream(des);
            //ImageIO获取图片流信息
            Image image=ImageIO.read(file.getInputStream());
            int width=image.getWidth(null); //获取原图宽度
            int height=image.getHeight(null);//获取原图高度
            int wrate=width/WIDTH;    //宽度缩略图
            int hrate=height/HEIGHT;//高度缩略图
            int rate=0;
            if (wrate>hrate) {//宽度缩略图比例大于高度缩略图,使用宽度缩略图
                rate=wrate;
            } else {
                rate=hrate;
            }
            //计算缩略图最终的宽度和高度
            int newWidth=width/rate;
            int newHeight=height/rate;
            
            BufferedImage bufferedImage=new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
            //图片缩略图实现
            bufferedImage.getGraphics().drawImage(image.getScaledInstance(newWidth, newHeight, image.SCALE_SMOOTH), 0, 0, null);
            //*image/jpeg
            String imageType=file.getContentType().substring(file.getContentType().indexOf("/")+1);
            ImageIO.write(bufferedImage, imageType, oStream);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                oStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //缩略图返回的相对路径
        return uploadPath+"/thum_"+file.getOriginalFilename();
    }
}

  配置信息一,web容器配置,web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    metadata-complete="true" version="3.0">
    <display-name>ImageCompress</display-name>
    <!-- 设置前端拦截器,springmvc容器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!-- springmvc具体配置信息 -->
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <!-- 状态1表示,web应用是随web容器启动而启动 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- Map all requests to the DispatcherServlet for handling -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- 表示拦截所有的url路径 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

  配置信息二,springmvc容器配置,spring-mvc.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 开启注解 -->
    <mvc:annotation-driven/>
    <!-- 注意:在spring的配置文件中,配置包扫描器时,只使用了*,想扫描所有的包,这种会造成错误;而这种方式有可能扫描到spring自带的包, 造成错误 -->
    <!-- *表示扫描所有子包下面的注解文件 -->
    <!-- <context:component-scan base-package="com.*"/> -->
    <!-- 表示扫描所有包下面所有java文件的注解文件 -->
    <context:component-scan base-package="com.thumbnail"/>
    <!-- 文件上传 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"></property>
        <property name="maxUploadSize" value="10485760000"></property>
        <property name="maxInMemorySize" value="40960"></property>
    </bean>
    <!-- 当在web.xml 中 DispatcherServlet使用 <url-pattern>/</url-pattern> 映射时,能映射静态资源 -->
    <mvc:default-servlet-handler />
    <!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用html)- -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="contentType" value="text/html" />
        <property name="prefix" value="/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>