当前位置: 移动技术网 > IT编程>移动开发>Android > Android如何高效显示较大的Bitmaps

Android如何高效显示较大的Bitmaps

2019年07月24日  | 移动技术网IT编程  | 我要评论

漯河天气预报查询,猪坚强变身宠物猪,金硅达

一、高效加载较大的bitmaps

     图片有各种形状和各种大小,在很多情况下,图片的实际大小都比图片在应用中所显示的大小要大的多,比如android系统自带的 gallery  应用显示的照片实际的分辨率通常比手机设备的密度要高很多

     考虑到我们是在开发一款内存使用受限的应用,理想的情况下,我们只是想把一个低分辨率版本的位图载入内存,一般来说这个低分辨率版本的位图要跟ui元件实际需要显示的大小相符。一张高分辨率的图片并不会给我们带来任何明显的好处,但却会占用宝贵的内存资源和产生额外的性能开销

二、获取bitmap的尺寸大小和类型

     bitmapfactory 类为我们提供了几种decoding方法(decodebytearray(), decodefile(),decoderesource(), etc)来从不同的来源创建出 bitmap ,如何选择最恰当的decode方法取决于你的图片数据来源,这些方法都会去尝试申请内存来构建bitmap对象,所有很容易就会导致一个outofmemory  异常,每种类型的decode方法都有额外的签名来让你通过 bitmapfactory.options 类来指定decoding选项,当我们decoding的时候把injustdecodebounds 属性设置为true 可以避免申请内存,虽然会返回一个null bitmap对象 ,但是会为我们传入的bitmapfactory.options  对象设置 outwidth, outheight and outmimetype 等属性的值,这个技术可以让你在构建bitmap对象之前事先知道它的大小和类型

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; 

为了避免java.lang.outofmemory  异常,在decoding bitmap之前你有必要去检测bitmap的大小和类型,除非你真的是非常清楚你要decoding的bitmap的大小,还有这个大小要适合当前应用内存环境

三、载入‘缩小版'的bitmap到内存

     现在我们已经知道了bitmap的大小,这将有助于我们来决策是载入整张bitmap还是载入'缩小版'的bitmap,这里有一些因素需要进行考虑:

1、载入整张图片预计要使用多少内存

2、在考虑到其它方面内存需要的情况下,你想把多少数量的内存给bitmap使用:

3、用于显示bitmap的 imageview 控件或其它ui元件的大小

4、当前设备屏幕的大小和密度    

例如,一点都不值得载入1024x768  像素的图片到内存中,而最终只在128x96 像素大小的 imageview 控件上显示       

我们应该告诉decoder,图像需要进行抽样,载入一个更小号的bitmap到内存中,设置 bitmapfactory.options 对象的 insamplesize 属性为true 。例如,一张分辨率为2048x1536 像素的图片,如果decode的时候把insamplesize   设置为4,那么得到的最终图片的大小大约为512x384 ,载入内存耗费0.75m而不是载入整张时的12m (假设位图的配置为 argb_8888) ,下面有一个在目标高和宽基础上计算insamplesize 的方法

public static int calculateinsamplesize( 
   bitmapfactory.options options, int reqwidth, int reqheight) { 
 // raw height and width of image 
 final int height = options.outheight; 
 final int width = options.outwidth; 
 int insamplesize = 1; 
 
 if (height > reqheight || width > reqwidth) { 
  if (width > height) { 
   insamplesize = math.round((float)height / (float)reqheight); 
  } else { 
   insamplesize = math.round((float)width / (float)reqwidth); 
  } 
 } 
 return insamplesize; 
} 

note :  insamplesize  值是2的幂的话,对于decoder来说会更快和更高效。然而,如果你想把调整过大小的位图缓存到内存或硬盘上时,依然非常有意义decoding最合适的位图大小,这样有助于节省内存或节省硬盘空间

下面是一个获取位图的方法

public static bitmap decodesampledbitmapfromresource(resources res, int resid, 
  int reqwidth, int reqheight) { 
 
 // first decode with injustdecodebounds=true to check dimensions 
 final bitmapfactory.options options = new bitmapfactory.options(); 
 options.injustdecodebounds = true; 
 bitmapfactory.decoderesource(res, resid, options); 
 
 // calculate insamplesize 
 options.insamplesize = calculateinsamplesize(options, reqwidth, reqheight); 
 
 // decode bitmap with insamplesize set 
 options.injustdecodebounds = false; 
 return bitmapfactory.decoderesource(res, resid, options); 
} 

这个方法可以很容易的做到在任意显示尺寸大小的ui元件中去载入一张位图

mimageview.setimagebitmap( 
 decodesampledbitmapfromresource(getresources(), r.id.myimage, 100, 100)); 

在其他的bitmapfactory.decode*  系列的decode方法中以上获取位图的技术也是需要的。

以上就是本文的全部内容,希望对大家学习android软件编程有所帮助。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网