为什么要对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图片采样缩放的更多相关文章
-
Android 图片的缩放与旋转
本文实现Android中的图片的缩放效果 首先设计布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res ...
-
Android图片的缩放效果
一.概述 Android 图片要实现:手势滑动,双击变大,多点触控的效果. 其实是有一定难度的,我们需要用Matrix ,GestureDetector 等等需要完成一个复杂的逻辑才能实现,然而今天我 ...
-
android图片拖动缩放
这篇图片拖拽缩放也是我在项目中用到的,今天整理一下,将源码奉献给大家,希望对大家以后碰到相似的问题有帮助.android 大图片拖拽缩放 这篇就不做过多介绍了,直接上源码: public class ...
-
Android图片旋转,缩放,位移,倾斜,对称完整示例(一)——imageView.setImageMatrix(matrix)和Matrix
MainActivity如下: import android.os.Bundle; import android.view.MotionEvent; import android.view.View; ...
-
Android图片处理--缩放
PS:在开发中我们会遇到一些图片处理问题,比如说缓存图片了.限制图片大小了.查看图片了等.上一篇文章介绍了图片的全景效果查看,今天介绍一个图片缩放,我们如果有时间的话,可以自己写一个属于自己的库,里面 ...
-
Android图片旋转,缩放,位移,倾斜,对称完整演示样例(一)——imageView.setImageMatrix(matrix)和Matrix
MainActivity例如以下: import android.os.Bundle; import android.view.MotionEvent; import android.view.Vie ...
-
android图片的缩放、圆角处理
android中图片缩放方法有三种:1,bitmapFactory:2,bitmap+metrix:3,thumbUtil 方法一:bitmapFactory: public static Bitma ...
-
[android] 图片的缩放
界面布局,线性布局,竖直排列,两个ImageView 获取到两个ImageView对象 调用BitmapFactory.decodeResource(res,id)方法,获取Bitmap对象 参数:r ...
-
Android动画及图片的缩放和旋转
Android动画有2种,一种是Tween Animation,另一种是Frame Animation,先说说Tween动画吧. Tween动画是对视图对象中的内容进行一系列简单的转换,比如位置的移动 ...
随机推荐
-
自学silverlight 5.0
这是一个silverlight游戏:http://keleyi.com/keleyi/phtml/silverlight/ 接了个单子,非要用Silverlight 5来作一个项目,之前从来没接触过这 ...
-
iOS两个框架之间的类型转换--";桥接";技术
话不多说,直接举例说明吧.场景模拟:需要开发一个通讯录相关功能,实现访问以及添加等等.这时,需要使用的框架是Core Foundation.而此框架使用的是C语言,例如:CFArrayRef,CFSt ...
-
[Sciter系列] MFC下的Sciter&ndash;2.Sciter中的事件,tiscript,语法
[Sciter系列] MFC下的Sciter–2.Sciter中的事件,tiscript,CSS部分自觉学习,重点说明Tiscript部分的常见语法和事件用法. 本系列文章的目的就是一步步构建出一个功 ...
-
转载:C++ 虚函数表解析
目录(?)[+] 转载:http://blog.csdn.net/haoel/article/details/1948051# 前言 C++中 的虚函数的作用主要是实现了多态的机制.关于多态,简而 ...
-
tkinter中鼠标与键盘事件(十五)
鼠标与键盘事件 import tkinter wuya = tkinter.Tk() wuya.title("wuya") wuya.geometry("300x200+ ...
-
JDK源码分析(9) LinkedHashMap
概述 LinkedHashMap是一个关联数组.哈希表,它是线程不安全的,允许key为null,value为null.他继承自HashMap,实现了Map<K,V>接口.其内部还维护了一个 ...
-
docker与虚拟机的区别
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...
-
cxGrid导出Excel货币符号问题
cxGrid导出到Excel,对于Currency类型总是加上了货币符号,可以修改导出文件设置来去掉: 在cxXLSExport.pas文件中,修改: procedure TcxXLSExportPr ...
-
ImageMagick、imagick和ghostscript三者的关联
http://467754239.blog.51cto.com/4878013/1602518/ 一.功能概述 ImageMagick是第三方的图片处理软件,功能要比GD强大.建议两者都安装,并不冲突 ...
-
c#中的模态对话框和非模态对话框
模态对话框弹出窗口阻止调用窗口的所有消息响应.只有在弹出窗口结束后调用窗口才能继续.在模态窗口“关闭”后,可以读取模态窗口中信息,包括窗口的返回状态,窗口子控件的值. 非模态对话框可以在弹出窗口和调用 ...