关闭

Android:图片处理小结

标签: android图片
716人阅读 评论(0) 收藏 举报
分类:

图片处理在安卓开发中十分重要,因为:

  1. 系统资源有限,系统为单个应用分配的内存也有限;
  2. 图片占用大量内存,例如一张2592x1936像素的图片,如果以ARGB_8888编码,会占据2592*1936*4 bytes约19M的内存,这无疑会很容易造成OOM!
  3. 一些控件尤其是AdapterView,会需要加载较多图片,处理不当也会OOM。

本文全部内容均来源于官方文档Displaying Bitmaps Efficiently,简单小结一下方便以后自己快速查找。


1、高效加载大图,Displaying Bitmaps Efficiently

通常我们加载图片的分辨率是会大于屏幕的分辨率,所以加载大内存的图片对于显示效果来说是不会有任何好处的;
解决方法:

1)获得图片的一些信息,包括实际高度宽度,而不加载到内存

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);

2)通过实际所需来计算图片的压缩比例,options.inSampleSize,算法也比较简单,实际高度不断除半来和所需高度比较即可。

3)真正加载压缩后的图片到内存,

options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);


2、在子线程处理图片

1)异步任务方式来处理,官方推荐是AsyncTask;
2)注意并发问题


3、缓存图片

内存缓存

使用内存缓存技术之前,需要先考虑一些问题以选择一个合适的缓存内存大小。

  • How memory intensive is the rest of your activity and/or application?
  • How many images will be on-screen at once? How many need to be available ready to come on-screen?
  • What is the screen size and density of the device? An extra high density screen (xhdpi) device like Galaxy Nexus will need a larger cache to hold the same number of images in memory compared to a device like Nexus S (hdpi).
  • What dimensions and configuration are the bitmaps and therefore how much memory will each take up?
  • How frequently will the images be accessed? Will some be accessed more frequently than others? If so, perhaps you may want to keep certain items always in memory or even have multiple LruCache objects for different groups of bitmaps.
  • Can you balance quality against quantity? Sometimes it can be more useful to store a larger number of lower quality bitmaps, potentially loading a higher quality version in another background task.

使用LruCache类来实现内存缓存,看了源码感觉兼容包android.support.v4.util.LruCache才是真正LRU算法,而android.util.LruCache处理掉的是RU的,不知道有没分析错误!还是使用兼容包保险点。

final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

    // Use 1/8th of the available memory for this memory cache.
    final int cacheSize = maxMemory / 8;

    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            // The cache size will be measured in kilobytes rather than
            // number of items.
            return bitmap.getByteCount() / 1024;
        }
    };
    ...

直接调用LruCache对象的put和get方法就可以了,使用上还是比较简单的。


磁盘缓存

SDK中并没有磁盘缓存的工具类,但是JakeWharthon大神写了个官方认证的硬盘缓存类。
https://android.googlesource.com/platform/libcore/+/jb-mr2-release/luni/src/main/java/libcore/io/DiskLruCache.java
硬盘缓存的使用没有内存那么方便,需要自己封装一下,主要使用:

  1. 通过获得一个输出流来保存缓存文件;
    DiskLruCache.Editor editor = mDiskLruCache.edit(key);
    OutputStream outputStream = editor.newOutputStream(0);
  2. 通过获得一个输入流来读取缓存文件;
    DiskLruCache.Snapshot snapShot = mDiskLruCache.get(key);
    InputStream inputStream = snapShot.getInputStream(0);

4、管理图片内存

不同版本的android内存管理方式有所不同,比如说

  1. 2.2之前GC时会停止所有线程;2.3以后可以并发GC,所以当Bitmap对象不再被引用时就会被回收;
  2. 2.3.3(API 10)之前,像素数据是存放在native memory的,和存储在Dalvik堆Bitmap对象本身分离。

管理图片内存:
1)在2.3.3之前,使用recycle()方法可以让GC尽快回收Bitmap对象,通过一些计数的方式来确定Bitmap对象确实不再使用,从而合理地使用recycle()方法;

2)在3.0之后,使用BitmapFactory.Options.inBitmap字段,如果这个选项被选择,解码方法加载数据时将尝试重复利用已经存在的Bitmap对象。


最后推荐一下郭霖大神的博客,http://blog.csdn.net/guolin_blog里面有一系列相关的文章!

0
0
查看评论

图片处理小结

1.数码相机照片特别大3m以上,内存吃不消,只显示原图的1/8 通过BitmapFactory.Options 来实现 BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOption...
  • u010333409
  • u010333409
  • 2013-10-20 15:09
  • 403

Android开发常用开源框架:图片处理

1、图片加载,缓存,处理 框架名称 功能描述 Android Universal Image Loader 一个强大的加载,缓存,展示图片的库,已过时 Picasso 一个强大的图片下载与缓存的库 Fresco 一个用于管理图像和他们使用的内存的库 Glide ...
  • axi295309066
  • axi295309066
  • 2017-02-25 00:46
  • 11879

Android 图片处理工具类汇总

很有用的Android图片处理工具,实现各种图片处理效果
  • shell812
  • shell812
  • 2015-11-11 14:27
  • 1585

Android中常见的图片处理框架的简单使用

在我们日常的开发过程中,我们免不了要跟图片打交道,尤其是网络图片,在我们处理这些问题的时候,较为常见的会遇到这样几个问题:一是OOM内存溢出,二是图片尺寸与缩略图处理的平衡,三是网络图片的加载与缓存机制,我们自己去处理这些问题的时候往往是比较麻烦的,常见的解决方案就是使用封装好的图片框架进行处理,我...
  • JArchie520
  • JArchie520
  • 2017-01-10 10:26
  • 1210

图片处理小结1

    2016年被称为人工智能的元年。随着AlphaGo战胜李世石,人工只能再一次站在时代的风口浪尖。但是人工智能觉不仅限于AlphaGo打败李世石这样一个应用,在智慧安防,智慧交通,智慧医疗,智慧语音等等无不渗透着人工智能的身影。2017年,人工智能已经上升到国家战略层面。2...
  • wjplearning
  • wjplearning
  • 2018-02-09 20:59
  • 4

Android常见的图片处理的开源框架

注意:第三方图片处理框架内部都已经封装了LruCatch,用来处理大图的加载,避免了OOM异常,使用了线程池来管理线程,避免了开启多个线程造成的资源的浪费,对于更新UI,内部也已经封装了Handler来进行线程间通信,将数据发送到UI线程来进行更新UI线程1、Glide:默认使用Hurlconnec...
  • qq_32890771
  • qq_32890771
  • 2017-08-03 22:57
  • 526

android大图、高清图片处理

Android大图、高清图片处理 Android中,系统分配给手机app的内存是有限的,现阶段根据不同的手机分配的最大内存也不一样,少的只有几十M。当我们以Bitmap的形式把高清的大图加载到内存当中时,它占用的内存会成倍数的增加。占用的内存超过了系统能够提供给app的内存时,会产生OOM。 ...
  • u013279462
  • u013279462
  • 2017-05-23 10:50
  • 231

Android 图片处理 常用代码快之二

import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Bitmap.Config; import android....
  • ebirdfighter
  • ebirdfighter
  • 2014-06-26 12:15
  • 364

android实验三 简单聊天记录的设计与实现

v/:* {behavior:url(#default#VML);}o/:* {behavior:url(#default#VML);}w/:* {behavior:url(#default#VML);}.shape {behavior:url(#default#VML);} Normal 0...
  • ssduer
  • ssduer
  • 2011-06-06 21:20
  • 1907

Android Studio学习小结

今天在移交项目的时候编译Studio报以下错误:这里给出一个可能的原因是因为Android的方法数目不够,添加以下代码试试: multiDexEnabled true,希望能解决,谢谢
  • yumaoda
  • yumaoda
  • 2017-03-08 09:39
  • 115
    个人资料
    • 访问:92107次
    • 积分:1802
    • 等级:
    • 排名:千里之外
    • 原创:87篇
    • 转载:0篇
    • 译文:0篇
    • 评论:19条
    最新评论