文档章节

位图管理、图片下载缓存、管理图片内存(二)高效下载大图

k
 kim366
发布于 2016/05/13 19:36
字数 1059
阅读 4
收藏 0

        图片可能包含各种形状和尺寸,在许多情况下,他们可能会超出UI组件的尺寸要求,比如,系统的相册应用展示设备相机拍的照片,这些照片像素可能会超出设备的屏幕尺寸。由于应用的内存限制,你可能只想在内存中持有分辨率更低的版本,这个版本应该跟UI组件上展示的尺寸相匹配。高分辨率不一定提供明显的好处,但是仍然占用着宝贵的内存,并可能因为附加的扩展产生额外的性能开销。这一节将学习,在不超过单个应用内存限的情况下,通过加载小分辨率的图片样品的方式解码大容量位图。

 

        读取位图的规模和类型

        位图工厂类提供了一些解码方法(decodeByteArray(),decodeFile(),decodeResource()等),用于通过不同的资源创建一个位图,使用时基于你的图片数据资源,应选择最合适的解码方法。这些方法试图为构造好的位图分配内存,所以会很容易导致内存溢出问题。每个类型的解码方法都有附加的签名,使你可以通过BitmapFactory.Option类指定解码的选项。设置inJustDecodeBounds属性为true,解码时可以避免内存分配,返回null给位图对象,并能够设置outWidth和outHeight和outMimeType。这种技术允许你在位图构造或分配内存之前读取图片数据的尺寸和类型。

        要想避免内存溢出,可以在解码图片之前检查位图的规模,除非你明确知道提供的图片资源在可获得的内存容量范围之内。

  

       加载缩略版本到内存中

       既然图片的规模是已知的,就可以决定是将图片完整地加载大内存中,还是加载一个缩小的样本。下面是一些需要考虑的因素:
       1. 估算加载完整图片到内存中的内存使用量。
       2. 在应用加载图片时,可以获得的内存容量。
       3. 需要加载图片的目标ImageView或者UI组件的规模。
       4. 当前设备的屏幕尺寸和像素。


       例如,如果图片最终展示在一个128*96的指甲大小的ImageView中,那么加载一个1024*768像素的图片到内存是很不值的。
       解码到一个图片样品中,加载一个缩小的版本到内存中,设置BitmapFactory.Option对象的inSampleSize值为true。比如,一张分辨率为2048*1536的图片可以被解码为四分之一大小的分辨率为512*384的样品图片。加载这张图片只需要0.75M内存而不是完整图片的12M内存(假设位图格式为ARGB_888),下面是一个计算样品尺寸值的方法,该方法基于二次幂相除得到一个width和height值。

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}
注意:要使用这个方法,首先通过设置isJustDecodeBounds值为true进行解码,将这个options传递进来,然后通过设置新的图片样品的isSampleSize的isJustDecodeBounds值为true再次进行解码。

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

这个方法使加载任意的大尺寸位图到ImageView中变得更加容易,并且可以通过下列方法将图片展示到100*100像素的图片中。

mImageView.setImageBitmap(
    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));


你可以以相似的过程从其他资源中解码位图,只要通过合适的解码方法BitmapFactory.decode*取代即可。










本文转载自:http://blog.csdn.net/oyangyujun/article/details/41038879

共有 人打赏支持
k
粉丝 1
博文 129
码字总数 0
作品 0
朝阳
私信 提问
Android图片缓存之初识Glide

前言: 前面总结学习了图片的使用以及Lru算法,今天来学习一下比较优秀的图片缓存开源框架。技术本身就要不断的更迭,从最初的自己使用SoftReference实现自己的图片缓存,到后来做电商项目自...

丁佳辉
2017/10/18
0
0
Android中的缓存处理

一、缓存介绍 (一)、Android中缓存的必要性: 1、没有缓存的弊端: 流量开销:对于客户端——服务器端应用,从远程获取图片算是经常要用的一个功能,而图片资源往往会消耗比较大的流量。 ...

墨宇hz
2015/04/25
0
0
Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类)

最新内容建议直接访问原文:Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类) 介绍总结的一些android公共库,包含缓存(图片缓存、预取缓存)、公共View(下拉及底部...

Trinea
2013/07/28
839
1
【Google官方教程】前言:高效的Bitmap显示

转载声明:Ryan的博客文章欢迎您的转载,但在转载的同时,请注明文章的来源出处,不胜感激! :-) http://my.oschina.net/ryanhoo/blog/88153 译者:Ryan Hoo 来源:https://developer.andro...

RyanHoo
2012/11/09
0
11
总结的一些android公共库

最新最准确内容建议直接访问原文:Android公共库(缓存 下拉ListView 下载管理Pro 静默安装 root运行 Java公共类) 介绍总结的一些android公共库,包含缓存(图片缓存、预取缓存)、公共View(下拉...

Trinea
2012/07/16
0
1

没有更多内容

加载失败,请刷新页面

加载更多

php isset,emtpy,is_null,真假值判断小记

<?phpheader("Content-type:text/html; charset='utf-8'");echo "<pre>";$a = '';$b = ' ';$c = "\r\n";$d = 0;$e = false;$f = null;var_dump(strlen($a),strlen($b),str......

病态S
11分钟前
0
0
PHP 关于常用函数的使用总结

strpos() 函数返回字符串在另一个字符串中第一次出现的位置。   如果没有找到该字符串,则返回 false。 strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。该函数返回字符串的其余...

koothon
14分钟前
0
0
Groovy秘诀

Groovy秘诀 听说java世界里有个Groovy大神!java需要半天处理的事情,Groovy只需要几分钟,是的,几分钟…剩下来的时间,程序员终于有时间泡妹子了,^_^…….技术宅的兄弟,赶紧来看看吧。 首...

白石
20分钟前
0
0
不能在FROM子句中为更新指定目标表 (You can't specify target table 'xxx' for update in FROM clause )

在select外边套一层,让数据库认为你不是查同一表的数据作为同一表的更新数据: update user_basic set is_new=1 where id IN( SELECT a.id FROM ( SELECT user_basic.id FROM user_basic,st...

郭周园
24分钟前
0
0
idea上实现github代码同步

https://www.cnblogs.com/liangzhilin/p/6106090.html

踏破铁鞋无觅处
27分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部