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. (error) DENIED Redis is running in protected mode because protected mode is enabled

    在通过Java程序链接配置好的redis服务时出现 DENIED Redis is running in protected mode because protected mode is enable ...

  2. apache 把404页面的url转发给php脚本处理

    # .htaccess1 RewriteCond %{REQUEST_FILENAME} !-f 2 RewriteRule ^(.*)$ map.php?host=%{HTTP_HOST}& ...

  3. Oracle 使用序列、触发器实现自增

    之前项目开发多用mysql,对于id自增长设置,只需要简单修改列属性便好.最近改用ORACLE,头大一圈.ORACLE的相关操作,多用脚本.想短平快,难.最终用sql developer通过UI进行修 ...

  4. Java工具类-转换字符编码

    package common; /** *字符串处理公用类 */ public class DealString { /** * 转换字符编码 由“iso-8859-1”西文转换为简体中文 */ pu ...

  5. 洛谷P1007 独木桥 [数论]

    题目传送门 独木桥 题目背景 战争已经进入到紧要时间.你是运输小队长,正在率领运输部队向前线运送物资.运输任务像做题一样的无聊.你希望找些刺激,于是命令你的士兵们到前方的一座独木桥上欣赏风景,而你留在 ...

  6. 洛谷P3539 [POI2012] ROZ-Fibonacci Representation

    题目传送门 转载自:five20,转载请注明出处 本来看到这题,蒟蒻是真心没有把握的,还是five20大佬巨orz 首先由于斐波拉契数的前两项是1,1 ,所以易得对于任何整数必能写成多个斐波拉契数加减 ...

  7. Bzoj1486/洛谷P3199 最小圈(0/1分数规划+spfa)/(动态规划+结论)

    题面 Bzoj 洛谷 题解(0/1分数规划+spfa) 考虑\(0/1\)分数规划,设当前枚举到的答案为\(ans\) 则我们要使(其中\(\forall b_i=1\)) \[ \frac{\sum ...

  8. Sqli-labs less 9

    Less-9 本关我们从标题就可以看到 <基于时间-单引号>,所以很明显的这关要我们利用延时注入进行,同时id参数进行的是 ' 的处理.这里我们大致的将延时注入的方法演示一次. 这里用sl ...

  9. 背包问题(dp基础)

    题目描述: 在N件物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数).求背包能够容纳的最大价值. Input 第1 ...

  10. [Codeforces #211] Tutorial

    Link: Codeforces #211 传送门 一套非常简单的题目,但很多细节都是错了一次才能发现啊…… 还是不能养成OJ依赖症,交之前先多想想corner case!!! A: 模拟,要特判0啊 ...