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

时间:2022-02-15 09:14:27

最近做项目需要图片压缩处理,网上找的方法大都使用了 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类来进行处理的替代方案,代码如下:
可以压缩为任意大小,压缩后高清,不变形(留白),可以改后缀名,可以修改压缩分辨率。
可能有朋友也有这个需要,参考一下吧,有问题还请指证!

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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;
  }
 
}