服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android整理好的图片压缩工具类

Android整理好的图片压缩工具类

2022-09-01 13:21franksight Android

今天小编就为大家分享一篇关于Android整理好的图片压缩工具类,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

Android设备的内存有限,对于大图片,必须进行压缩后再进行显示,否则会出现内存溢出:OOM;

处理策略:

1.使用缩略图(Thumbnails);

Android系统会给检测到的图片创建缩略图;可以操作Media内容提供者中的Image对图片进行操作;

2.手动压缩:

  • (1)根据图片和屏幕尺寸,等比压缩,完美显示;
  • (2)降低图片质量,压缩图片大小;

以下是自己整理的小工具类(对于按比例缩放后,在此并未再进行质量缩放,此时图片大小有可能超出我们期望的限制;假如我们有严格的大小限制需求,可先进行按比例缩放后,判断此时图片大小是否超出限制;如果超出限制,对其再进行质量缩放即可。建议使用按比例缩放,按质量缩放很有可能导致图片失真。)

?
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
</pre><p><pre name="code" class="java">package com.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
/**
 * 图片压缩工具类
 * @author 丶Life_
 */
public class ImageCompressUtil {
  /**
   * 通过降低图片的质量来压缩图片
   * @param bmp
   *      要压缩的图片位图对象
   * @param maxSize
   *      压缩后图片大小的最大值,单位KB
   * @return 压缩后的图片位图对象
   */
  public static Bitmap compressByQuality(Bitmap bitmap, int maxSize) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int quality = 100;
    bitmap.compress(CompressFormat.JPEG, quality, baos);
    System.out.println("图片压缩前大小:" + baos.toByteArray().length + "byte");
    boolean isCompressed = false;
    while (baos.toByteArray().length / 1024 > maxSize) {
      quality -= 10;
      baos.reset();
      bitmap.compress(CompressFormat.JPEG, quality, baos);
      System.out.println("质量压缩到原来的" + quality + "%时大小为:"
          + baos.toByteArray().length + "byte");
      isCompressed = true;
    }
    System.out.println("图片压缩后大小:" + baos.toByteArray().length + "byte");
    if (isCompressed) {
      Bitmap compressedBitmap = BitmapFactory.decodeByteArray(
          baos.toByteArray(), 0, baos.toByteArray().length);
      recycleBitmap(bitmap);
      return compressedBitmap;
    } else {
      return bitmap;
    }
  }
  /**
   * 传入图片url,通过压缩图片的尺寸来压缩图片大小
   * @param pathName 图片的完整路径
   * @param targetWidth 缩放的目标宽度
   * @param targetHeight 缩放的目标高度
   * @return 缩放后的图片
   */
  public static Bitmap compressBySize(String pathName, int targetWidth,
      int targetHeight) {
    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inJustDecodeBounds = true;// 不去真的解析图片,只是获取图片的头部信息,包含宽高等;
    Bitmap bitmap = BitmapFactory.decodeFile(pathName, opts);
    // 得到图片的宽度、高度;
    int imgWidth = opts.outWidth;
    int imgHeight = opts.outHeight;
    // 分别计算图片宽度、高度与目标宽度、高度的比例;取大于等于该比例的最小整数;
    int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth);
    int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight);
    if (widthRatio > 1 || heightRatio > 1) {
      if (widthRatio > heightRatio) {
        opts.inSampleSize = widthRatio;
      } else {
        opts.inSampleSize = heightRatio;
      }
    }
    // 设置好缩放比例后,加载图片进内容;
    opts.inJustDecodeBounds = false;
    bitmap = BitmapFactory.decodeFile(pathName, opts);
    return bitmap;
  }
  /**
   * 传入bitmap,通过压缩图片的尺寸来压缩图片大小 
   * @param bitmap 要压缩图片
   * @param targetWidth 缩放的目标宽度
   * @param targetHeight 缩放的目标高度
   * @return 缩放后的图片
   */
  public static Bitmap compressBySize(Bitmap bitmap, int targetWidth,
      int targetHeight) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(CompressFormat.JPEG, 100, baos);
    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inJustDecodeBounds = true;
    bitmap = BitmapFactory.decodeByteArray(baos.toByteArray(), 0,
        baos.toByteArray().length, opts);
    // 得到图片的宽度、高度;
    int imgWidth = opts.outWidth;
    int imgHeight = opts.outHeight;
    // 分别计算图片宽度、高度与目标宽度、高度的比例;取大于该比例的最小整数;
    int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth);
    int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight);
    if (widthRatio > 1 || heightRatio > 1) {
      if (widthRatio > heightRatio) {
        opts.inSampleSize = widthRatio;
      } else {
        opts.inSampleSize = heightRatio;
      }
    }
    // 设置好缩放比例后,加载图片进内存;
    opts.inJustDecodeBounds = false;
    Bitmap compressedBitmap = BitmapFactory.decodeByteArray(
        baos.toByteArray(), 0, baos.toByteArray().length, opts);
    recycleBitmap(bitmap);
    return compressedBitmap;
  }
  /**
   * 通过压缩图片的尺寸来压缩图片大小,通过读入流的方式,可以有效防止网络图片数据流形成位图对象时内存过大的问题;
   * @param InputStream 要压缩图片,以流的形式传入
   * @param targetWidth 缩放的目标宽度
   * @param targetHeight 缩放的目标高度
   * @return 缩放后的图片
   * @throws IOException 读输入流的时候发生异常
   */
  public static Bitmap compressBySize(InputStream is, int targetWidth,
      int targetHeight) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buff = new byte[1024];
    int len = 0;
    while ((len = is.read(buff)) != -1) {
      baos.write(buff, 0, len);
    }
    byte[] data = baos.toByteArray();
    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inJustDecodeBounds = true;
    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,
        opts);
    // 得到图片的宽度、高度;
    int imgWidth = opts.outWidth;
    int imgHeight = opts.outHeight;
    // 分别计算图片宽度、高度与目标宽度、高度的比例;取大于该比例的最小整数;
    int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth);
    int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight);
    if (widthRatio > 1 || heightRatio > 1) {
      if (widthRatio > heightRatio) {
        opts.inSampleSize = widthRatio;
      } else {
        opts.inSampleSize = heightRatio;
      }
    }
    // 设置好缩放比例后,加载图片进内存;
    opts.inJustDecodeBounds = false;
    bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
    return bitmap;
  }
  /**
   * 旋转图片摆正显示
   * @param srcPath
   * @param bitmap
   * @return
   */
  public static Bitmap rotateBitmapByExif(String srcPath, Bitmap bitmap) {
    ExifInterface exif;
    Bitmap newBitmap = null;
    try {
      exif = new ExifInterface(srcPath);
      if (exif != null) { // 读取图片中相机方向信息
        int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
            ExifInterface.ORIENTATION_NORMAL);
        int digree = 0;
        switch (ori) {
        case ExifInterface.ORIENTATION_ROTATE_90:
          digree = 90;
          break;
        case ExifInterface.ORIENTATION_ROTATE_180:
          digree = 180;
          break;
        case ExifInterface.ORIENTATION_ROTATE_270:
          digree = 270;
          break;
        }
        if (digree != 0) {
          Matrix m = new Matrix();
          m.postRotate(digree);
          newBitmap = Bitmap.createBitmap(bitmap, 0, 0,
              bitmap.getWidth(), bitmap.getHeight(), m, true);
          recycleBitmap(bitmap);
          return newBitmap;
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    return bitmap;
  }
  /**
   * 回收位图对象
   * @param bitmap
   */
  public static void recycleBitmap(Bitmap bitmap) {
    if (bitmap != null && !bitmap.isRecycled()) {
      bitmap.recycle();
      System.gc();
      bitmap = null;
    }
  }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对服务器之家的支持。如果你想了解更多相关内容请查看下面相关链接

原文链接:https://blog.csdn.net/whj9073/article/details/53196357

延伸 · 阅读

精彩推荐