Android异步载入全解析之大图处理

异步载入中很重要的一部分就是对图像的处理,这也是我们前面用异步载入图像做示例的原因。

一方面是由于图像处理不好的话会很占内存,并且easyOOM,还有一方面,图像也比文字要大,载入比較慢。所以,在解说了怎样进行多线程、AsyncTask进行多线程载入后,先暂停下后面的学习。来对图像的异步处理进行一些优化工作。

为什么要对图像处理

为什么要对图像进行处理,这是一个很直接的问题。一张图像。无论你拿手机、相机、单反还是什么玩意拍出来,它就有一定的大小,可是在不同的终端上,终端也有不同的大小。比方一张超高请无码大图,10M大小,在网页中看着挺爽。全高清,毛孔都看得清。

相同一张图片。假设放在4.7寸的手机上,当然,相同还是一张高清无码大图,但这张图片10M,在电脑上可能不算什么,但在手机上,已经是很大了,而这张图片在手机上,你拼命看。也就是那样,即使分辨率降低一半。你看上去也还是差点儿相同。

这就像所谓的视网膜屏、2k屏、4k屏,事实上已经基本达到视觉分析的极限了。一般情况下,区别并不大。

可是,尽管你看着区别不大,但对系统来说。区别就很大了,手机的内存。要像使用你藏的私房钱一样,每一分都要三思而用。

所以。我们在下载高分辨率的图片的时候。能够对图像进行压缩,显示上尽管没有太大区别,可是却帮系统节省了大量的私房钱。

BitmapFactory之inSampleSize

BitmapFactory是Android中提供的对图像的解析方法。通过它的一些静态方法。我们能够对图像进行解析。比如从文件里解析——decodeFile;从资源中解析——decodeResource。从网络中解析——decodeStream等等。
当我们从网络上进行图像下载的时候,看情况,是否须要对图像进行压缩,那么怎样在系统不载入图像到内存之前,就获取图像的大小等參数呢?看上去很矛盾,但系统给我们提供了一种简单的解决方法。
BitmapFactory提供了BitmapFactory.Options參数。这个參数有一个inJustDecodeBounds属性。当这个属性为true的时候,我们就能够禁止系统载入图像到内存。可是。!!

这时候,Options參数中的图像宽高、类型等属性已经被赋值了,这样。我们就实现了空手套白狼,哦,不正确,是不使用内存就获取图像的属性。

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
// 获取属性值
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
在获得了图像的參数之后,我们就能够对图像进行对应的处理了。比如我们显示图像的ImageView仅仅有200 X 200 像素,而我们的图片有800 X 800 像素,那你把这么大的一张图放到这么小的ImageView中,有啥用呢?白白浪费了内存。OK,那么以下我们就来对图像进行压缩,Options參数中给我们提供了这样一个属性——inSampleSize,这个属性能够设置图像的缩放比例,比如一张1000 X 1000像素的图像。设置inSampleSize为5。意思就是把这个图像缩放到了五分之中的一个。即200 X 200 。

OK,以下我们就通过这样一个方法来对图像进行优化,首先,我们须要创建一个方法来获取到一个合适的inSampleSize:

/**
* 获取合适的inSampleSize
* @param options
* @param targetWidth 期望Width
* @param targetHeight 期望Height
* @return
*/
public static int getInSampleSize(BitmapFactory.Options options,
int targetWidth, int targetHeight) {
// 原始图片的高度和宽度
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > targetHeight || width > targetWidth) {
// 计算出实际宽高和目标宽高的比率
final int heightRate = Math.round((float) height / (float) targetHeight);
final int widthRate = Math.round((float) width / (float) targetWidth);
inSampleSize = heightRate < widthRate ? heightRate : widthRate;
}
return inSampleSize;
}

方法很easy。就是通过期望长宽来获取缩放的比例。以下我们就创建一个方法来获取缩放后的图像。这里为了演示,我们仅仅创建从资源文件里获取图像的方法:

/**
* 使用targetWidth、targetHeight来获取合适的inSampleSize
* 并使用inSampleSize来缩放得到合适大小的图像
* @param res getResources()
* @param resId id
* @param targetWidth
* @param targetHeight
* @return
*/
public static Bitmap decodeSuitableBitmap(Resources res, int resId,
int targetWidth, int targetHeight) {
// 空手套白狼
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// 计算合适的inSampleSize
options.inSampleSize = getInSampleSize(options, targetWidth, targetHeight);
// 载入到内存
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}

通过调用decodeSuitableBitmap这样一个方法,我们就能够很easy的将图像进行压缩。

我的Github 我的视频 慕课网

Android异步载入全解析之大图处理的更多相关文章

  1. Android异步载入全解析之使用多线程

    异步载入之使用多线程 初次尝试 异步.异步,事实上说白了就是多任务处理.也就是多线程执行.多线程那就会有各种问题,我们一步步来看.首先.我们创建一个class--ImageLoaderWithoutC ...

  2. Android异步载入全解析之IntentService

    Android异步载入全解析之IntentService 搞什么IntentService 前面我们说了那么多,异步处理都使用钦定的AsyncTask.再不济也使用的Thread,那么这个Intent ...

  3. Android异步载入全解析之使用AsyncTask

    Android异步载入全解析之使用AsyncTask 概述 既然前面提到了多线程,就不得不提到线程池,通过线程池,不仅能够对并发线程进行管理.更能够提高他们运行的效率.优化整个App.当然我们能够自己 ...

  4. Android异步载入全解析之开篇瞎扯淡

    Android异步载入 概述 Android异步载入在Android中使用的很广泛,除了是由于避免在主线程中做网络操作.更是为了避免在显示时由于时间太长而造成ANR,添加显示的流畅性,特别是像List ...

  5. Android异步载入AsyncTask具体解释

    曾看见有人说过.认为非常有道理.分享一下:   技术分为术和道两种:   (1)具体做事的方法是术.   (2)做事的原理和原则是道. 近期项目发现个重大问题.结果打log跟踪查是AsyncTask导 ...

  6. Android 异步消息处理机制解析

    Android 中的异步消息处理主要由四个部分组成,Message.Handler.MessageQueue.Looper.下面将会对这四个部分进行一下简要的介绍. 1. Message: Messa ...

  7. Android系统启动过程全解析

    Android系统是一款基于Linux的移动操作系统,那么Android是如何启动起来的呢?本文就详细阐述Android系统的启动过程. 从内核之上,我们首先应该从文件系统的init开始,因为 ini ...

  8. Android异步载入学习笔记之四:利用缓存优化网络载入图片及ListView载入优化

    假设不做不论什么处理.直接用网络载入图片在网速快的情况下可能没什么不好的感觉.可是假设使用移动流量或是网络不好的时候.问题就来了,要么用户会抱怨流量使用太多.要么抱怨图片载入太慢.如论从哪个角度出发, ...

  9. Eclipse,到了说再见的时候了——Android Studio最全解析

    转自:http://blog.jobbole.com/77635/ 去年的Google大会上,Google带给我们一个小玩具——Android Studio,说它是玩具,是因为它确实比较菜,界面过时, ...

随机推荐

  1. hdu多校 2

    ... 后面四个小时都在挂机很难受. 1010 裸的逆序对 //#pragma comment(linker, "/stack:200000000") //#pragma GCC ...

  2. [thinkphp] 无限极分类

    <?php /* * 无限极分类 类 */ header("Content-Type: text/html; charset=UTF-8"); Class Category ...

  3. HDU 4607.Park Visit-树的直径(BFS版)+结论公式(乱推公式)-备忘(加油!)

    Park Visit Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. 启动Ubuntu时出现 /dev/sda2 clean 和 /dev/sda2 recovering journal 现象的解决办法

    最近在Ubuntu 18.4上安装Nvidia显卡后,显卡似乎总是不能完全兼容. 第一次出现问题时,是登录账号后,发现系统采用了默认显卡驱动,而已装过的显卡驱动则有损坏导致无法使用. 第二次出现问题时 ...

  5. 使用screen后台实时执行命令

    在做一个大体积的数据备份时,在远程终端上直接运行备份脚本back.sh,或运行back.sh&放到后台运行,此时关闭远程终端,或网络断开都会让命令停止运行.此时就要使用到screen命令. s ...

  6. xUtils 中的 BitmapUtils

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha xUtils框架,包括BitmapUtils.DbUtils.ViewUtils和Htt ...

  7. 【二分】【字符串哈希】【二分图最大匹配】【最大流】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem I. Minimum Prefix

    给你n个字符串,问你最小的长度的前缀,使得每个字符串任意循环滑动之后,这些前缀都两两不同. 二分答案mid之后,将每个字符串长度为mid的循环子串都哈希出来,相当于对每个字符串,找一个与其他字符串所选 ...

  8. mysql常见故障问题汇总

    Auth: JinDate: 20140414 UpdateDate: 继续更新 导库字符集的问题http://www.cnblogs.com/diege/p/3640618.htmlmysql-pr ...

  9. Maven命名规范收集

    一.基本命名规范: groupId:定义当前Maven项目隶属的实际项目,例如org.sonatype.nexus,此id前半部分org.sonatype代表此项目隶属的组织或公司,后部分代表项目的名 ...

  10. Nginx 重定向 伪静态 rewrite index.php

    参考https://www.kancloud.cn/manual/thinkphp5/177576 thinkphp入口文件同目录下添加.把下面的内容保存为.htaccess文件 <IfModu ...