小技巧工作生活

Android:图片压缩的几种方式

2019-07-04  本文已影响15人  绿茵场上的码者

1、前言

2、作用

通过图片压缩,实现内存优化,避免OOM异常

3、内存

图片占用内存计算公式:图片所占内存 = 图片的分辨率w * 图片的分辨率h * 一个像素占用的字节数

获取图片内存大小的代码如下:

public void getBitmapSize(View view) {
        File file = Environment.getExternalStorageDirectory();
        File originFile = new File(file,"dog.jpg");
        Bitmap originBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath());
        int bitmapSize = getBitmapSize(originBitmap);
        Log.i("测试","图片所占内存大小->" + bitmapSize);
}

4、分类

4.1、设置图片格式

Android目前常用的图片格式有pngjpegwebp等。

实验可得:同分辨下的一张图,jpeg格式下大小为124kb,而png格式下大小为2M

4.2、质量压缩

质量压缩并不会改变图片在内存中的大小,只会改变图片占用磁盘的大小,因为质量压缩改变的是图片的位深透明度来减少图片占用的磁盘空间大小;
根据内存计算公式知道,宽高都没变,所以内存并不会改变,所以想保持图片的质量同时减少图片所占用的磁盘空间大小,可以选用质量压缩,质量压缩的示例代码如下:

public void qualityCompress(Bitmap.CompressFormat format,int quality){
        File file = Environment.getExternalStorageDirectory();
        File originFile = new File(file,"dog.jpg");
        Bitmap originBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath());
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        originBitmap.compress(format,quality,bos);//quality:10=22.57,50=98.12kb,70=122.97kb
        int bitmapSize = getBitmapSize(originBitmap);
        Log.i("测试","质量压缩后图片所占内存大小->" + bitmapSize);//结果:5760000
        try {
            FileOutputStream fos = new FileOutputStream(new File(file,"resultQualityImg.jpg"));
            fos.write(bos.toByteArray());
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

}

注:质量压缩关键是quality的值,quality值与图片体积大小成反比,并且由于png是无损压缩,所以设置quality无效

4.3、采样率压缩

采样率压缩不仅能压缩图片内存大小,还可以减少图片体积大小,代码如下:

public void sampleRateCompress(int inSampleSize) {
        File file = Environment.getExternalStorageDirectory();
        File originFile = new File(file, "dog.jpg");
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = false;
        options.inSampleSize = inSampleSize;
        Bitmap resultBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath(), options);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        resultBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);//quality:100=215.38kb,80=50.41kb
        int bitmapSize = getBitmapSize(resultBitmap);
        Log.i("测试","采样率压缩后图片所占内存大小->" + bitmapSize);//结果:1440000
        try {
            FileOutputStream fos = new FileOutputStream(new File(file, "resultSampleRateImg.jpg"));
            fos.write(bos.toByteArray());
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

采样率压缩的关键是inSampleSize参数,假如inSampleSize设置为2,那么会导致图片的宽高都为1/2,而内存大小为1/4

注:采样率压缩图片也和quality参数有关,quality和图片体积大小成正比,和内存无关

4.4、尺寸压缩

尺寸压缩就是对图片进行一定的缩放,导致宽高的变化,达到压缩图片的目的;和采样率压缩一样,尺寸压缩也是能压缩图片内存大小,还可以减少图片体积大小,代码如下:

public void sizeCompress(int radio) {//radio:5=47.85kb,2=221.39kb
        File sdFile = Environment.getExternalStorageDirectory();
        File originFile = new File(sdFile, "dog.jpg");
        Bitmap bitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath());
        //设置缩放比
        Bitmap result = Bitmap.createBitmap(bitmap.getWidth() / radio, bitmap.getHeight() / radio, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        RectF rectF = new RectF(0, 0, bitmap.getWidth() / radio, bitmap.getHeight() / radio);
        //将原图画在缩放之后的矩形上
        canvas.drawBitmap(bitmap, null, rectF, null);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        result.compress(Bitmap.CompressFormat.JPEG, 100, bos);//
        int bitmapSize = getBitmapSize(result);
        Log.i("测试","尺寸压缩后图片所占内存大小->" + bitmapSize);//结果:230400
        try {
            FileOutputStream fos = new FileOutputStream(new File(sdFile, "resultSizeRateImg.jpg"));
            fos.write(bos.toByteArray());
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

尺寸压缩的关键是ratio参数,假如ratio设置为2,那么会导致图片的宽高都为1/2,而内存大小为1/4

注:尺寸压缩图片也和quality参数有关,quality和图片体积大小成正比,和内存无关
尺寸

5、采样率压缩和尺寸压缩的区别

从上面的实验结果看出,采样率压缩和尺寸压缩原理似乎的一样的,那么我们从压缩效果展示这两者的区别


原图 分辨率:1200*1200 大小:124kb 采样率压缩 分辨率:600*600 大小:78.2kb 尺寸压缩 分辨率:600*600 大小:74.4kb

6、总结

通过以上的压缩方法分类描述,相信你已经对图片压缩有了更深的了解,那么就可以根据不同的使用场景对相应的图片压缩方式进行选择了

7、案例下载

点我下载

上一篇 下一篇

猜你喜欢

热点阅读