首页 > 代码库 > Android百日程序:高效载入大图片

Android百日程序:高效载入大图片

问题:如果图片很大,全部载入内存,而显示屏又不大,那么再大的图片也不会提高视觉效果的,而且会消耗无谓的内存。

解决办法就是根据实际需要多大的图片,然后动态计算应该载入多大的图片;但是因为不太可能图片大小和实际需要的大小一致,故此需要载入图片大小为一个2的某次方的值,而大于实际需要的大小。


如图,载入一个微缩图大小为100*100


新建一个项目,

参考Google上的方法:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap

建立一个类,以便调用其中的函数处理图片资源,全部代码如下:

package bill.su.loadbitmap;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class BitmapUtils {

	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) {

			final int halfHeight = height / 2;
			final int halfWidth = width / 2;

			// Calculate the largest inSampleSize value that is a power of 2 and
			// keeps both
			// height and width larger than the requested height and width.
			while ((halfHeight / inSampleSize) > reqHeight
					&& (halfWidth / inSampleSize) > reqWidth) {
				inSampleSize *= 2;
			}
		}

		return inSampleSize;
	}

	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);
	}
}

主界面的xml代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="bill.su.loadbitmap.MainActivity" >

    <ImageView
        android:id="@+id/pandaImageView"
        android:layout_width="100px"
        android:layout_height="100px"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" />

</RelativeLayout>

使用ImageView来显示图片

主界面的逻辑代码添加代码:

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		ImageView imageView = (ImageView) findViewById(R.id.pandaImageView);
		imageView.setImageBitmap(BitmapUtils.decodeSampledBitmapFromResource(
				getResources(), R.drawable.panda, 100, 100));
	}
注意R.drawable.panda是怎么来的。只要在项目文件夹中的res文件夹的drawable文件夹添加一个图片命名为panda,在Eclipse刷新项目就会显示这个id了。如果没有drawable这个文件夹也不要紧,直接自己新建一个文件夹就可以了。

如果图片没有显示,很可能是图片资源不存在,这样项目是不会提示错误的,直接没有显示出来。


看看项目结构图,就知道如何建立这个项目了:


这里主要学习的代码是BitmapUtils中的代码,这样已经封装好了,以后可以当做自己的一个资源类调用了。




Android百日程序:高效载入大图片