Android图片采样缩放功能实例代码
为什么要对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图片采样缩放功能实例代码,希望对大家有所帮助
上一篇: C#使用linq查询大数据集的方法