最实用的Android图片内存优化的方法

本文深入探讨Android图片优化方法,包括尺寸压缩、质量压缩和内存重用,有效避免OOM问题,提升APP性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

习惯性的开始之前,美图镇楼

好好努力,大家都能美女簇拥

在实际开发过程中,我们经常会遇到所开发的APP加载缓慢甚至卡顿的问题,很大一部分原因就是图片造成的,这篇文章将对Android的图片进行优化以实现对性能的优化。

Android图片OOM问题的产生

可能的原因有以下3点:

  1. 一个页面一次加载过多的图片。 可能少量的图片加载对性能没有多大的影响,但是大量的图片对内存的占用是很可观的,而每个APP都是有内存限制的,大量的图片加载就可能直接超过了APP的内存限制,而直接OOM;
  2. 加载大图片没有进行压缩(尺寸,质量)。 对于大图片直接使用imageView.setImageResource()是不行的,需要对尺寸或质量进行优化;
  3. Android列表加载大量bitmap没有使用缓存。 需要使用缓存重用或者比较流行的图片加载框架如Glide,Fresco等,也是自带缓存功能的。

如何计算一张图片占用的内存?

一张图片占用的内存 = 图片的高度 * 图片的宽度 * 一个像素所占的内存

从这里我们就可以看出,对于图片优化可以从以下3个方面入手:

  1. 尺寸压缩; ps:就是减小图片的宽高。
    BitmapFactory.Options里面有个inJustDecodeBounds设置为true,就可以在不加载图片内存的情况下获取图片的宽高。从而计算出合适的压缩比inSampleSize,设置inSampleSize大于等于2,就可以降低图片的采样率,从而减小内存的占用。如果我们单纯的改变ImageView的大小不会对图片占用的内存有任何的优化作用,因为图片是存储在bitmap里面,只有对bitmap本身的优化才会起作用。

  2. 质量压缩; ps:就是改变一个像素占用的内存,内部是通过优化解码率来实现的。
    也就是解码率压缩,常见的PNG,JPG,WEBP等格式的图片在设置到UI上之前经过解码过程。通过解码率方面优化图片占用内存的方式:使用RGB_565替代ARGB_8888可以降低图片占用内存。因为它可以降低一个像素占用的内存大小,RGB_565的一个像素占2个字节,而ARGB_8888一个像素占4个字节。

  3. 内存重用; ps:可以通过Android提供的InBitmap来实现。
    InBitmap是Android3.0之后才能用的,使用了InBitmap的图片的内存大小是小于或者等于没有使用的图片内存大小。

代码演示(原图加载)

    /**
     * 加载原图
     * @param img 目标ImageView控件
     * @param filePath 图片路径
     */
    private void loadOriginalSize(ImageView img, String filePath) {
        Bitmap bitmap = BitmapFactory.decodeFile(filePath);
        img.setImageBitmap(bitmap);
    }

代码演示(图片压缩)

    /**
     * 压缩图片
     * @param img
     * @param filePath
     */
    private void picOptimize(ImageView img, String filePath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        //设置为true,就可以在不加载图片内存的情况下获取图片的宽高
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);

        //获取图片宽度
        int width = options.outWidth;
        //计算出合适的压缩比,width压缩到200px
        options.inSampleSize = width / 200;
        //降低每个像素所占的内存大小,一个像素只占用两个字节
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        //真正把压缩后的图片加载出来
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
        img.setImageBitmap(bitmap);
    }
}

代码演示(内存重用)

    /**
     * inBitmap的使用,内存重用
     * @param secondImg 第二张图片的控件
     * @param filePath 第二张图片的路径
     * @param firstBitmap 第一张图片的bitmap(第二张图片的内存将重用这个bitmap的内存)
     */
    private void picInBitmap(ImageView secondImg, String filePath, Bitmap firstBitmap) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inBitmap = firstBitmap;
        Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
        secondImg.setImageBitmap(bitmap);
    }

好了,图片的内存优化就到这里,后续还有关于图片缓存,懒加载的文章,关注我查看对应的文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值