美文网首页
Android性能优化:图片压缩

Android性能优化:图片压缩

作者: tianyl | 来源:发表于2019-02-10 19:37 被阅读0次

索引

一般来说,图片是Android中的资源使用的重要一块,不论是从流量上还是在内存上,对于图片的优化都是必不可少的,而且Android系统中的OOM也有很多时候是因为图片造成的,所以对于Android系统中图片的优化,可以说是很重要的一部分,而压缩,则是图片优化中必不可少的一步

目录

  1. 文件压缩
  2. 内存压缩

1 文件压缩

1 .1质量压缩

质量压缩是一种有损压缩,是Android系统提供的一种常用的图片压缩的API,通过使用Bitmap.compress可以对图片进行质量压缩

//format:压缩的格式
//quality:质量(png格式的图片会忽略此参数)
//stream:输出文件的地址
public boolean compress(CompressFormat format, int quality, OutputStream stream)

1.2 尺寸压缩

通过使用Bitmap.createScaledBitmap可以对图片进行尺寸压缩

//filter:图片滤波处理,true可以让色彩更丰富
Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)

还有一个方法可以对图片进行剪切

Bitmap.createBitmap (Bitmap source, int x, int y, int width, int height)

1.3 格式压缩

在上述两种压缩方式中,可以通过选择不同的图片格式进行压缩,一般来说,使用jpg有损压缩或webp压缩后文件的大小是小于使用png格式的图片

2 内存压缩

2.1 bitmap内存占用计算

  • ARGB_8888

    • ARGB各占8位,即width*height*4
  • RGB_565

    • R5位,G6位,B5位,即16位,width*height*2
  • getByteCount

    • 可以返回存储此位图像素的大小字节数
  • BitmapFactory.Options

    • 控制解码图片参数
    • inDensity:表示这个bitmap的像素密度,根据drawable目录
    • inTargetDensity:表示要被画出来时的目标(屏幕像素密度)

bitmap在加载一张图片时,会根据inDensity和inTargetDensity这两个值进行缩放

注意:bitmap的大小和文件大小没有关系,只和屏幕的分辨率和显示的大小有关

2.2 bitmap的复用

复用规则

可被复用的Bitmap必须设置inMutable为true;

  • Android4.4(API 19)之前只有格式为jpg、png,同等宽高(要求苛刻),inSampleSize为1的Bitmap才可以复用;
  • Android4.4(API 19)之前被复用的Bitmap的inPreferredConfig
    会覆盖待分配内存的Bitmap设置的inPreferredConfig;
  • Android4.4(API 19)之后被复用的Bitmap的内存
    必须大于等于需要申请内存的Bitmap的内存;
复用代码
/**
 *  缩放bitmap
 * @param context
 * @param id
 * @param maxW
 * @param maxH
 * @return
 */
public static Bitmap resizeBitmap(Context context,int id,int maxW,int maxH,boolean hasAlpha,Bitmap reusable){
    Resources resources = context.getResources();
    BitmapFactory.Options options = new BitmapFactory.Options();
        // 只解码出 outxxx参数 比如 宽、高
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(resources,id,options);
        //根据宽、高进行缩放
    int w = options.outWidth;
    int h = options.outHeight;
        //设置缩放系数
    options.inSampleSize = calcuteInSampleSize(w,h,maxW,maxH);
    if (!hasAlpha){
        options.inPreferredConfig = Bitmap.Config.RGB_565;
    }
    options.inJustDecodeBounds = false;
        // 需要设置为异变的才能够被复用内存
    options.inMutable = true;
    options.inBitmap = reusable;
    return BitmapFactory.decodeResource(resources,id,options);
}

/**
 * 计算缩放系数
 * @param w
 * @param h
 * @param maxW
 * @param maxH
 * @return 缩放的系数
 */
private static int calcuteInSampleSize(int w,int h,int maxW,int maxH) {
    int inSampleSize = 1;
    if (w > maxW && h > maxH){
        inSampleSize = 2;
            //循环 使宽、高小于 最大的宽、高
        while (w /inSampleSize > maxW && h / inSampleSize > maxH){
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

2.3 bitmap的内存位置

  • android3.0以下,bitmap的内存在native中
  • android3.0 ~ android8.0以下,bitmap内存在java中
  • android8.0及以上,bitmap内存在native中

对于在native中的bitmap,需要手动调用bitmap.recycle()进行释放内存,不如虚拟机只会回收Java层的内存,并不会回收native中的内存,所以需要维护一个线程回收bitmap,具体写法可以参考glide图片加载框架https://github.com/bumptech/glide/blob/master/library/src/main/java/com/bumptech/glide/load/engine/ActiveResources.java

总结

图片压缩分为文件压缩和内存压缩,一般来说文件压缩在设计师给出图片的时候即可完成,可以通过图片压缩的一些网站进行,内存压缩则需要根据产品具体的需求进行实现,虽然现在一般的图片加载框架中已经做了大部分功能,但是对于图片压缩的具体实现,还是需要有所了解为好

注:此文属作者原创,转载请标明出处

相关文章

网友评论

      本文标题:Android性能优化:图片压缩

      本文链接:https://www.haomeiwen.com/subject/thyxeqtx.html