为什么要对Android中的图片进行采样缩放呢?

是为了更加高效的加载Bitmap。假设通过imageView来显示图片,很多时候ImageView并没有图片的原始尺寸那么大,这时候把整张图片加载进来后再设给ImageView是没有必要的,因为ImagView并没有办法显示原始的图片。

所以我们可以使用BitmapFactory.Options按照一定的采样率加载缩小后的图片,将缩小后的图片在ImageView中显示,这样就能降低内存占用,在一定程度上避免OOM,提高bitma加载时候的性能。

BitmapFactory有一个参数:inSampleSize(采样率)。

inSampleSize为1,那么采样后图片大小等于原始图片大小。

inSampleSize为2,那么采样后图片宽高均为原始图片的1/2,像素为原图的1/4,占有的内存大小为原图的1/4。

例如:一张的图片像素为1024*1024,储存格式为ARGB8888格式储存,那么它占有内存1024*1024*4=4M,用采样率为2采样后内存占用为512*512*4=1M。

总结:inSampleSize是必须大于1的整数才有效果,小与1就相当于1,并且同时作用于宽高,所以缩放后的图片大小以采样率的2次方形式递减.根据最新的官方文档,inSampleSize的取值应该总是为2的指数,若给系统的inSampleSize不为2的指数,那么系统会向下取整并且选择一个最接近2的指数来代替,不过经过验证,这个结论并不是在所有的Android版本上都成立。

那么我们如何获取采样率呢?

1、将BitmapFactory.Option的inJustDecodeBound参数设为true,加载图片,这个时候图片并没有加载进内存,仅仅是去解析图片原始宽高信息而已。

2、从BitmapFactory.Option取出图片的原始宽高信息,对应于outWidth,outHeight参数。

3、根据采样率的规则和目标原始View的所需大小计算出采样率inSampleSize。

4、将BitmapFactory.Option的inJustDecodeBound参数设为false,重新加载图片,这时候图片才真正被载进内存。

以下提供一份代码模板:package com.example.chatting.chatting.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.util.DisplayMetrics;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView; public class ImagesTool
{
/**
* 根据ImageView的大小压缩图片
* @param path
* @param imageView
* @return
*/
public static Bitmap decodeSampledBitmapFromPath(String path,ImageView imageView)
{
Options options = new Options();
options.inJustDecodeBounds=true;
BitmapFactory.decodeFile(path,options); ImageSize imageSize=getImageViewSize(imageView); //获取图片大小,ImageSize是封装着ImageView大小的类 //计算采样率
options.inSampleSize=caculateInSampleSize(options,imageSize.width,imageSize.height); options.inJustDecodeBounds=false;
Bitmap bitmap=BitmapFactory.decodeFile(path, options);
return bitmap;
}
//计算采样率
public static int caculateInSampleSize(Options options,ImageView imageView)
{
ImageSize imageSize=getImageViewSize(imageView);
int inSampleSize=caculateInSampleSize(options, imageSize.width,imageSize.height);
return inSampleSize;
} /**
* 根据具体的大小要求解析图片
* @param path
* @param reqWidth
* @param reqHeight
* @return
*/
public static Bitmap decodeSampledBitmapFromPath(String path,int reqWidth, int reqHeight)
{
Options options = new Options();
options.inJustDecodeBounds=true;
BitmapFactory.decodeFile(path,options);
//计算采样率
options.inSampleSize=caculateInSampleSize(options,reqWidth,reqHeight); options.inJustDecodeBounds=false;
Bitmap bitmap=BitmapFactory.decodeFile(path, options);
return bitmap; }
//计算采样率
private static int caculateInSampleSize(Options options, int reqWidth, int reqHeight)
{ int width=options.outWidth; //原始图片宽
int height=options.outHeight; //原始图片高 int inSampleSize=1; //采样率
if(width>reqWidth || height>reqHeight) //原始的宽比目标宽大,或者原始高比目标高大
{
int widthRadio=Math.round(width *1.0f/reqWidth);
int heightRadio = Math.round(height * 1.0f / reqHeight);
inSampleSize = Math.max(widthRadio, heightRadio);
}
return inSampleSize;
}
//获取ImageView的大小
protected static ImageSize getImageViewSize(ImageView imageView)
{
ImageSize imageSize = new ImageSize(); DisplayMetrics metrics = imageView.getContext().getResources().getDisplayMetrics();
LayoutParams lp = imageView.getLayoutParams(); int width = imageView.getWidth();
if (width <= 0) {
width = lp.width;
}
if (width <= 0) {
width = imageView.getMaxWidth();
}
if (width <= 0) {
width = metrics.widthPixels;
} int height = imageView.getHeight();
if (height <= 0) {
height = lp.height;
}
if (height <= 0) {
height = imageView.getMaxHeight();
}
if (height <= 0) {
height = metrics.heightPixels;
} imageSize.width = width;
imageSize.height = height;
return imageSize;
}
//ImageView大小的封装类
private static class ImageSize
{
int width;
int height;
} }

Android图片采样缩放的更多相关文章

  1. Android 图片的缩放与旋转

    本文实现Android中的图片的缩放效果 首先设计布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res ...

  2. Android图片的缩放效果

    一.概述 Android 图片要实现:手势滑动,双击变大,多点触控的效果. 其实是有一定难度的,我们需要用Matrix ,GestureDetector 等等需要完成一个复杂的逻辑才能实现,然而今天我 ...

  3. android图片拖动缩放

    这篇图片拖拽缩放也是我在项目中用到的,今天整理一下,将源码奉献给大家,希望对大家以后碰到相似的问题有帮助.android 大图片拖拽缩放 这篇就不做过多介绍了,直接上源码: public class ...

  4. Android图片旋转,缩放,位移,倾斜,对称完整示例(一)——imageView.setImageMatrix(matrix)和Matrix

    MainActivity如下: import android.os.Bundle; import android.view.MotionEvent; import android.view.View; ...

  5. Android图片处理--缩放

    PS:在开发中我们会遇到一些图片处理问题,比如说缓存图片了.限制图片大小了.查看图片了等.上一篇文章介绍了图片的全景效果查看,今天介绍一个图片缩放,我们如果有时间的话,可以自己写一个属于自己的库,里面 ...

  6. Android图片旋转,缩放,位移,倾斜,对称完整演示样例(一)——imageView.setImageMatrix(matrix)和Matrix

    MainActivity例如以下: import android.os.Bundle; import android.view.MotionEvent; import android.view.Vie ...

  7. android图片的缩放、圆角处理

    android中图片缩放方法有三种:1,bitmapFactory:2,bitmap+metrix:3,thumbUtil 方法一:bitmapFactory: public static Bitma ...

  8. [android] 图片的缩放

    界面布局,线性布局,竖直排列,两个ImageView 获取到两个ImageView对象 调用BitmapFactory.decodeResource(res,id)方法,获取Bitmap对象 参数:r ...

  9. Android动画及图片的缩放和旋转

    Android动画有2种,一种是Tween Animation,另一种是Frame Animation,先说说Tween动画吧. Tween动画是对视图对象中的内容进行一系列简单的转换,比如位置的移动 ...

随机推荐

  1. 基于 jq 实现拖拽上传 APK 文件,js解析 APK 信息

    技术栈 jquery 文件上传:jquery.fileupload,github 文档 apk 文件解析:app-info-parser,github 文档 参考:前端解析ipa.apk安装包信息 - ...

  2. Java对象的克隆和深浅问题

    Java实现克隆的方式 Java实现克隆的方式有如下两种, 推荐采用实现Cloneable接口的方式 实现Cloneable接口, 重写clone方法, 调用父类的clone方法 还有另一种方法, 不 ...

  3. 我面试过没有上万人也有十几个,简历要这么写才有hr要你

    今天终于有时间好好给大家写写关于如何写简历,给自己加分了. 这篇文章拖了很久了应该说,本来想在上周写的,但是事情实在是太多,又不想草草了事,所以搁置到现在.今天早上正好空出来了,就马上给大家码出来了. ...

  4. Spring中Model、ModelMap及ModelAndView之间的区别+传递参数

    org.springframework.ui.Model(接口)传递数据,Spring框架自动创建它的一个实现类,如BindingAwareModelMap org.springframework.u ...

  5. Java使用OkHttps工具类调用外部接口

    前言 现在公司业务已止不是传统的增删改查等简单的业务处理操作,而是对数据各种联调三方接口与其他系统进行交互等,那么就需要我们在后台java中进行外部接口的调用,本文采用OkHttps工具类对接微信接口 ...

  6. SVN切换账号

    问题背景 SVN账号在登录的时候,默认是保存在个人电脑的 C:\Users\Administrator\AppData\Roaming\Subversion\auth\svn.simple\ 目录下的 ...

  7. (转)p解决 java.util.prefs.BackingStoreException 报错问题

    原文:https://blog.csdn.net/baidu_32739019/article/details/78405444 https://developer.ibm.com/answers/q ...

  8. Java后端工程师必备书单(含大后端方向相关书籍)

    学习Java和其他技术的资源其实非常多,但是我们需要取其精华去其糟粕,选择那些最好的,最适合我们的,同时也要由浅入深,先易后难.基于这样的一个标准,我在这里为大家提供一份Java的学习资源清单. 一: ...

  9. dubbo自定义异常传递信息丢失问题解决

    访问我的博客 目前计划对已有的单体项目进行组织架构拆分,调研了分布式系统中常用中间件 Dubbo 和 Spring Cloud,选择了 Dubbo,可以对当前现有项目进行平滑升级改造.但是一开始就遇到 ...

  10. 【InfluxDB】InfluxDB学习实践笔记

    InfluxDB是用Go编写的一个开源分布式时序.事件和指标数据库,无需外部依赖.它与Elasticsearch.Graphite等类似.比较适用于与事件紧密相关的数据,例如实时日志数据.实时监控数据 ...