Android如何高效显示较大的Bitmaps

一、高效加载较大的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软件编程有所帮助。

(0)

相关推荐

  • Android中使用BitmapShader类来制作各种图片的圆角

    public   BitmapShader(Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY) 调用这个类来产生一个画有一个位图的渲染器(Shader). bitmap:在渲染器内使用的位图 (1)tileX:The tiling mode for x to draw the bitmap in.   在位图上X方向花砖模式 (2)tileY:The tiling mode for y to draw the bitmap in.

  • android bitmap compress(图片压缩)代码

    android的照相功能随着手机硬件的发展,变得越来越强大,能够找出很高分辨率的图片.有些场景中,需要照相并且上传到服务,但是由于图片的大小太大,那么就上传就会很慢(在有些网络情况下),而且很耗流量,要想速度快,那么就需要减小图片的大小.减少图片的大小有两种方法,1. 照小图片: 2. 压缩大图片. 照相时获取小图片一般不太符合要求,因为,图片的清晰度会很差,但是这种情况有个好处就是应用速度会快些: 压缩图片,就是把大图片压缩小,降低图片的质量,在一定范围内,降低图片的大小,并且满足需求(图片仍

  • 解析Android开发优化之:对Bitmap的内存优化详解

    1) 要及时回收Bitmap的内存 Bitmap类有一个方法recycle(),从方法名可以看出意思是回收.这里就有疑问了,Android系统有自己的垃圾回收机制,可以不定期的回收掉不使用的内存空间,当然也包括Bitmap的空间.那为什么还需要这个方法呢? Bitmap类的构造方法都是私有的,所以开发者不能直接new出一个Bitmap对象,只能通过BitmapFactory类的各种静态方法来实例化一个Bitmap.仔细查看BitmapFactory的源代码可以看到,生成Bitmap对象最终都是通

  • Android界面 NotificationManager使用Bitmap做图标

    今天看到EOE问答里面有这"[Android 界面]NotificationManager 如何使用Bitmap做图标"这样一个问题,在论坛搜索也没有好的案例 特写一个简单的demo供大家参考 今天发布的是NotificationManager 使用Bitmap做图标 关键code 复制代码 代码如下: public void notification(int flag) { Notification notification = new Notification(); //设置sta

  • Android Bitmap和Drawable相互转换的简单代码

    很多开发者表示,不知道Android的Drawable和Bitmap之间如何相关转换.下面Android123给大家两种比较简单高效的方法. 一.Bitmap转Drawable 复制代码 代码如下: Bitmap bm=xxx; //xxx根据你的情况获取 BitmapDrawable bd=BitmapDrawable(bm); Android开发网提示因为BtimapDrawable是Drawable的子类,最终直接使用bd对象即可. 二. Drawable转Bitmap 转成Bitmap对

  • android将Bitmap对象保存到SD卡中的方法

    本文实例讲述了android将Bitmap对象保存到SD卡中的方法.分享给大家供大家参考.具体如下: Bitmap logoBitmap = BitmapFactory.decodeResource(mcontext.getResources(), R.drawable.arcnote_logo); ByteArrayOutputStream logoStream = new ByteArrayOutputStream(); boolean res = logoBitmap.compress(B

  • android中Bitmap的放大和缩小实例代码

    复制代码 代码如下: /**Bitmap放大的方法*/ private static Bitmap big(Bitmap bitmap) { Matrix matrix = new Matrix(); matrix.postScale(1.5f,1.5f); //长和宽放大缩小的比例 Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true); return

  • Android Bitmap详细介绍

    复制代码 代码如下: package com.testbitmapscale; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import com.testbitmapscale.R.drawable; im

  • android保存Bitmap图片到指定文件夹示例

    复制代码 代码如下: /** 保存方法 */ public void saveBitmap() { Log.e(TAG, "保存图片"); File f = new File("/sdcard/namecard/", picName); if (f.exists()) { f.delete(); } try { FileOutputStream out = new FileOutputStream(f); bm.compress(Bitmap.CompressFor

  • Android Activity之间传递图片(Bitmap)的方法

    在Android开发中:Activity之间传递参数是常见的事:如果我们要在Activity之间传递图片:1.MainActivity中包括一个ImageView:当我们点击ImageView时:把图片传递给另外一个Activity MainActivity的主要代码: 复制代码 代码如下: Intent intent=new Intent(MainActivity.this,TranActivity.class);            intent.putExtra("bitmap"

随机推荐