帅哥镶金牙 2021-05-28 09:39 采纳率: 0%
浏览 19

android图片管理怎么防止oom?

android图片上传要压缩吗?

android图片加载要压缩吗?

android图片怎么防止oom?

  • 写回答

2条回答 默认 最新

  • 小P聊技术 2021-05-28 09:44
    关注

    图片像素

    Android中图片有四种属性,分别是:
    ALPHA_8:每个像素占用1byte内存
    ARGB_4444:每个像素占用2byte内存
    ARGB_8888:每个像素占用4byte内存 (默认)
    RGB_565:每个像素占用2byte内存

     

    BitmapFactory.Options opt = new BitmapFactory.Options();  
     opt.inPreferredConfig = Bitmap.Config.RGB_565; // 图像以RGB_565读取
    

    Android默认的颜色模式为ARGB_8888,这个颜色模式色彩最细腻,显示质量最高。但同样的,占用的内存也最大。 所以在对图片效果不是特别高的情况下使用RGB_565(565没有透明度属性)

    图片大小边界压缩

    直接使用ImageView显示bitmap会占用较多资源,特别是图片较大的时候,可能导致崩溃。
    使用BitmapFactory.Options设置inSampleSize, 这样做可以减少对系统资源的要求。
    属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4。

    图片OOM的原理:
    假设一张图片的宽高为2600 * 1800 像素,每个像素是ARGB_8888,则其直接拉进内 存,占用的内存大小为:
    2600 * 1800 * 4byte = 18720000byte = 17.8M
    若展示此图片的ImageView大小仅为260 * 180px,则加载这么大的图片是没什么意义的,经计算,压缩比为10(2600 / 260),即inSampleSize = 10;
    经过边界压缩后,图片的大小为:
    260 * 180 * 4byte = 0.18M

     

            BitmapFactory.Options newOpts = new BitmapFactory.Options();  
            //开始读入图片,此时把options.inJustDecodeBounds 设回true了  
            newOpts.inJustDecodeBounds = true;  
            Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空  
      
            newOpts.inJustDecodeBounds = false;  
            int w = newOpts.outWidth;  
            int h = newOpts.outHeight;  
           
            float hh = 260f;//这里设置高度为260f
            float ww = 180f;//这里设置宽度为180f
            //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
            int be = 1;//be=1表示不缩放  
            if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放  
                be = (int) (newOpts.outWidth / ww);  
            } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放  
                be = (int) (newOpts.outHeight / hh);  
            }  
            if (be <= 0)  
                be = 1;  
            newOpts.inSampleSize = be;//设置缩放比例  
            //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
            bitmap = BitmapFactory.decodeFile(srcPath, newOpts);  
            return compressImage(bitmap);//压缩好比例大小后再进行质量压缩  
        }  
    
    

    图片回收

    使用Bitmap过后,就需要及时的调用Bitmap.recycle()方法来释放Bitmap占用的内存空间,而不要等Android系统来进行释放。

     

    // 先判断是否已经回收  
    
    if(bitmap != null && !bitmap.isRecycled()){  
    
        // 回收并且置为null  
    
        bitmap.recycle();  
    
        bitmap = null;  
    
    }  
    
    System.gc();
    

    常见图片加载框架

    Glide

    目前用的这个

    Univeral-Image-Loader

    l 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹assets中以及drawable中等
    l 支持随意的配置ImageLoader,例如线程池,图片下载器,内存缓存策略,硬盘缓存策略,图片显示选项以及其他的一些配置
    l 支持图片的内存缓存,文件系统缓存或者SD卡缓存
    l 支持图片下载过程的监听
    l 根据控件(ImageView)的大小对Bitmap进行裁剪,减少Bitmap占用过多的内存
    l 较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片,一般使用在ListView,GridView中,滑动过程中暂停加载图片,停止滑动的时候去加载图片
    l 提供在较慢的网络下对图片进行加载

    Picasso

    l 使用ListView,GridView的时候,自动检测Adapter的重用,取消下载,使用缓存
    l 将图像进行变换,以更好的适应布局控件等,减小内存开销
    l 进行图形变换,也可以写自己的变换类,但是必须实现Transformation接口
    l 支持设置加载之前的图片,和加载失败后的图片
    l 支持加载资源文件的图片
    l 支持加载sdcard中的图片文件

    Fresco

    FaceBook出品
    Fresco综合了之前图片加载库的优点的基础上利用本地代码做了性能上的优化

    评论

报告相同问题?

悬赏问题

  • ¥60 许可证msc licensing软件报错显示已有相同版本软件,但是下一步显示无法读取日志目录。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥30 关于<main>标签页面跳转的问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加
  • ¥15 用ns3仿真出5G核心网网元