详解Java中使用ImageIO类对图片进行压缩的方法_java

最近做项目需要图片压缩处理,网上找的方法大都使用了 com.sun.image.codec.jpeg.* 这个包中的JPEGImageEncoder类,引入这个包后一直报错,各种google百度,尝试了各种方法,包括手动引jre中的rt.jar,以及在eclipse中把受访问限制的API提示从ERROR改为WARNING,等等,然而这些都是不好使的,因为后来我发现我的java-7-openjdk-amd64中的rt.jar里边根本就没有com.sun.image.*,貌似这个类在java7中已经被彻底remove了,至少我这个版本是没有了。然后搜了个使用ImageIO类来进行处理的替代方案,代码如下:
可以压缩为任意大小,压缩后高清,不变形(留白),可以改后缀名,可以修改压缩分辨率。
可能有朋友也有这个需要,参考一下吧,有问题还请指证!

package cn.com.images; 

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList; 

import javax.imageio.ImageIO; 

/***
 * 对图片进行操作
 *
 * @author chenzheng_java
 * @since 2011/7/29
 *
 */
public class ImageHelper { 

  private static ImageHelper imageHelper = null; 

  public static ImageHelper getImageHelper() {
    if (imageHelper == null) {
      imageHelper = new ImageHelper();
    }
    return imageHelper;
  } 

  /***
   * 按指定的比例缩放图片
   *
   * @param sourceImagePath
   *      源地址
   * @param destinationPath
   *      改变大小后图片的地址
   * @param scale
   *      缩放比例,如1.2
   */
  public static void scaleImage(String sourceImagePath,
      String destinationPath, double scale,String format) { 

    File file = new File(sourceImagePath);
    BufferedImage bufferedImage;
    try {
      bufferedImage = ImageIO.read(file);
      int width = bufferedImage.getWidth();
      int height = bufferedImage.getHeight(); 

      width = parseDoubleToInt(width * scale);
      height = parseDoubleToInt(height * scale); 

      Image image = bufferedImage.getScaledInstance(width, height,
          Image.SCALE_SMOOTH);
      BufferedImage outputImage = new BufferedImage(width, height,
          BufferedImage.TYPE_INT_RGB);
      Graphics graphics = outputImage.getGraphics();
      graphics.drawImage(image, 0, 0, null);
      graphics.dispose(); 

      ImageIO.write(outputImage, format, new File(destinationPath));
    } catch (IOException e) {
      System.out.println("scaleImage方法压缩图片时出错了");
      e.printStackTrace();
    } 

  } 

  /***
   * 将图片缩放到指定的高度或者宽度
   * @param sourceImagePath 图片源地址
   * @param destinationPath 压缩完图片的地址
   * @param width 缩放后的宽度
   * @param height 缩放后的高度
   * @param auto 是否自动保持图片的原高宽比例
   * @param format 图图片格式 例如 jpg
   */
  public static void scaleImageWithParams(String sourceImagePath,
      String destinationPath, int width, int height, boolean auto,String format) { 

    try {
    File file = new File(sourceImagePath);
    BufferedImage bufferedImage = null;
    bufferedImage = ImageIO.read(file);
      if (auto) {
        ArrayList<Integer> paramsArrayList = getAutoWidthAndHeight(bufferedImage,width,height);
        width = paramsArrayList.get(0);
        height = paramsArrayList.get(1);
        System.out.println("自动调整比例,width="+width+" height="+height);
      } 

    Image image = bufferedImage.getScaledInstance(width, height,
        Image.SCALE_DEFAULT);
    BufferedImage outputImage = new BufferedImage(width, height,
        BufferedImage.TYPE_INT_RGB);
    Graphics graphics = outputImage.getGraphics();
    graphics.drawImage(image, 0, 0, null);
    graphics.dispose();
    ImageIO.write(outputImage, format, new File(destinationPath));
    } catch (Exception e) {
      System.out.println("scaleImageWithParams方法压缩图片时出错了");
      e.printStackTrace();
    } 

  } 

  /**
   * 将double类型的数据转换为int,四舍五入原则
   *
   * @param sourceDouble
   * @return
   */
  private static int parseDoubleToInt(double sourceDouble) {
    int result = 0;
    result = (int) sourceDouble;
    return result;
  } 

  /***
   *
   * @param bufferedImage 要缩放的图片对象
   * @param width_scale 要缩放到的宽度
   * @param height_scale 要缩放到的高度
   * @return 一个集合,第一个元素为宽度,第二个元素为高度
   */
  private static ArrayList<Integer> getAutoWidthAndHeight(BufferedImage bufferedImage,int width_scale,int height_scale){
    ArrayList<Integer> arrayList = new ArrayList<Integer>();
    int width = bufferedImage.getWidth();
    int height = bufferedImage.getHeight();
    double scale_w =getDot2Decimal( width_scale,width); 

    System.out.println("getAutoWidthAndHeight width="+width + "scale_w="+scale_w);
    double scale_h = getDot2Decimal(height_scale,height);
    if (scale_w<scale_h) {
      arrayList.add(parseDoubleToInt(scale_w*width));
      arrayList.add(parseDoubleToInt(scale_w*height));
    }
    else {
      arrayList.add(parseDoubleToInt(scale_h*width));
      arrayList.add(parseDoubleToInt(scale_h*height));
    }
    return arrayList; 

  } 

  /***
   * 返回两个数a/b的小数点后三位的表示
   * @param a
   * @param b
   * @return
   */
  public static double getDot2Decimal(int a,int b){ 

    BigDecimal bigDecimal_1 = new BigDecimal(a);
    BigDecimal bigDecimal_2 = new BigDecimal(b);
    BigDecimal bigDecimal_result = bigDecimal_1.divide(bigDecimal_2,new MathContext(4));
    Double double1 = new Double(bigDecimal_result.toString());
    System.out.println("相除后的double为:"+double1);
    return double1;
  } 

}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 图片
, 压缩
imageIO
java imageio 压缩png、imageio压缩图片、imageio质量压缩、java imageio.write、java imageio,以便于您获取更多的相关知识。

时间: 2024-10-23 11:13:45

详解Java中使用ImageIO类对图片进行压缩的方法_java的相关文章

详解Java中使用泛型实现快速排序算法的方法_java

快速排序算法概念快速排序一般基于递归实现.其思路是这样的: 1.选定一个合适的值(理想情况中值最好,但实现中一般使用数组第一个值),称为"枢轴"(pivot). 2.基于这个值,将数组分为两部分,较小的分在左边,较大的分在右边. 3.可以肯定,如此一轮下来,这个枢轴的位置一定在最终位置上. 4.对两个子数组分别重复上述过程,直到每个数组只有一个元素. 5.排序完成. 基本实现方式: public static void quickSort(int[] arr){ qsort(arr,

详解java中的Collections类_java

一般来说课本上的数据结构包括数组.单链表.堆栈.树.图.我这里所指的数据结构,是一个怎么表示一个对象的问题,有时候,单单一个变量声明不堪大用,比如int,String,double甚至一维数组.二维数组无法完全表达你要表达的东西,而定义一个类Class有太过麻烦,这时候,你可以考虑一下用Java中的Collections类.使用Collections类,必须在文件头声明import java.util.*; 一.动态.有序.可变大小的一维数组Vector与ArrayList  Collectio

详解Java中的时区类TimeZone的用法_java

一.TimeZone 简介TimeZone 表示时区偏移量,也可以计算夏令时. 在操作 Date, Calendar等表示日期/时间的对象时,经常会用到TimeZone:因为不同的时区,时间不同. 下面说说TimeZone对象的 2种常用创建方式.1.获取默认的TimeZone对象使用方法: TimeZone tz = TimeZone.getDefault() 2.使用 getTimeZone(String id) 方法获取TimeZone对象使用方法: // 获取 "GMT+08:00&qu

详解Java类库的概念以及import的使用方法_java

Java类库及其组织结构(Java API) Java 官方为开发者提供了很多功能强大的类,这些类被分别放在各个包中,随JDK一起发布,称为Java类库或Java API. API(Application Programming Interface, 应用程序编程接口)是一个通用概念. 例如我编写了一个类,可以获取计算机的各种硬件信息,它很强大很稳定,如果你的项目也需要这样一个功能,那么你就无需再自己编写代码,将我的类拿来直接用就可以.但是,我的类代码很复杂,让你读完这些代码不太现实,而且我也不

详解Java获取环境变量及系统属性的方法_java

环境变量这个概念不陌生, 就是操作系统的环境变量. 系统变量就是java本身维护的变量. 通过 System.getProperty 的方式获取. 对于不同的操作系统来说, 环境变量的处理可能会有一些不统一的地方, 比如说: 不区分大小写 等等. Java 获取环境变量Java 获取环境变量的方式很简单: System.getEnv()  得到所有的环境变量 System.getEnv(key) 得到某个环境变量的值   Map map = System.getenv(); Iterator i

详解Java中的正则表达式

详解Java中的正则表达式,并列出常用的正则表达式语法和一些常用的场景. 判断一个字符串是否是由数字组成: 当不使用正则表达式的时候的实现代码: public class RegexDemo01 { public static void main(String[] args) { String s = "23432324"; char c[] = s.toCharArray();//将字符串转换成字符数组 for (int i = 0; i < c.length; i++) {

详解Java中的指针、引用及对象的clone

对象|详解 Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文会试图澄清这一概念.并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象.本文会让你了解什么是影子clone与深度clone,认识它们的区别.优点及缺点.看到这个标题,是不是有点困惑:Java语言明确说明取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,滥用指针写成的

详解Java中用于查找对象哈希码值的hashCode()函数_java

理解hashCode() 的作用是获取哈希码,也称为散列码:它实际上是返回一个int整数.这个哈希码的作用是确定该对象在哈希表中的索引位置. hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数. 虽然,每个Java类都包含hashCode() 函数.但是,仅仅当创建并某个"类的散列表"(关于"散列表"见下面说明)时,该类的hashCode() 才有用(作用是:确定该类的每一个对象在散列表中的位

详解Java中的File文件类以及FileDescriptor文件描述类_java

File File 是"文件"和"目录路径名"的抽象表示形式. File 直接继承于Object,实现了Serializable接口和Comparable接口.实现Serializable接口,意味着File对象支持序列化操作.而实现Comparable接口,意味着File对象之间可以比较大小:File能直接被存储在有序集合(如TreeSet.TreeMap中).1. 新建目录的常用方法方法1:根据相对路径新建目录. 示例代码如下(在当前路径下新建目录"d