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中的代码,这样已经封装好了,以后可以当做自己的一个资源类调用了。

时间: 2024-12-17 11:48:05

Android百日程序:高效载入大图片的相关文章

图片--Android有效解决加载大图片时内存溢出的问题

Android有效解决加载大图片时内存溢出的问题 博客分类: Android Android游戏虚拟机算法JNI 尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存. 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView

android客户端加载网络大图片如何避免内存溢出

在Android开发中加载sdcard上的大图片到内存时容易导致OOM异常,常见的解决办法是基于BitmapFactory.Options类提供的方法定义指定的解码方式,设置inJustDecodeBounds属性为true,避免分配内存,返回一个null的Bitmap对象(包含outWidth,outHeightandoutMimeType),然后读取图片的尺寸和类型.再根据屏幕的高和宽对图片进行缩放,最后将缩放的图片加载到内存,主要代码如下: 1 Options opts = new Opt

Android百日程序:GridView实现相册效果

本章使用GridView控件来做一个相册效果. 图片效果如下: 响应点击事件,点击的时候提示是当前第几章图片,从左到右,从上到下. 点击了第一张图片,显示了1. 步骤: 一 新建项目,然后把图片资源拷贝到res/drawable/文件夹中,如果没有drawable这个文件夹也不要紧,可以直接新建这个文件夹,然后在Eclipse项目中刷新,就会在项目中显示出来了 二 然后在Layout的界面xml文件activity_main.xml(当然也可以随意自己喜欢命名),输入如下代码: <?xml ve

Android百日程序:使用Intent回传结果

本章使用Intent,回传需要的结果: 流程: 启动主页->按下按键启动第二个activity->输入用户名,按下OK按键->回传用户名回主页->主页读取用户名并显示出来. 1 启动主页图: 2 启动第二个activity 3 输入用户名: 4 回传到主页,读取并显示: 新建项目,然后输入对应的代码就OK了. 1 主页界面代码(activity_main.xml): <LinearLayout xmlns:android="http://schemas.androi

Android有效解决加载大图片时内存溢出的问题

尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图, 因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存. 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source, decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsse

Android百日程序 开篇章:Intent打开网页

学习一下人家100日写100个网页的做法,我也用100日写100个完整的Android程序. 这些程序的最基本要求: 1 完整性-每个程序都必须是独立可运行的 2 不重复性-所用的重点知识点都不一样 开篇章: --本章参考书本:Hello Android 编写一个简单的页面,如下,图1: 在文本框输入网址,图2: 点击按钮GO,然后就可以打开这个网站了, 图3: 步骤: 一  首先,新建一个项目,具体参数设置可以参照我的项目设置,如下: 主要看 1 src下的Browser.java:主要的ja

Android百日程序: Fragment动态管理和生命期

之前写过Fragment使用的程序,Fragment可以静态,也可以动态载入内存中的,这一章进一步看看如何动态地更换Fragment和看看Fragment生命期都有什么函数. 本章利用响应菜单点击事件,轮流载入不同的Fragment,显示不同的界面,效果如下: 开始的是没有载入Fragmen为空白: 点击菜单的NEXT FRAGMENT VIEW,就进入下一个界面,载入两个: 继续点击显示Fragment 1: 继续点击,显示Fragment2: 然后就是循环了: 如此循环显示不同画面. 一 首

Android百日程序:进度条对话框实现

显示由Activity管理的dialog. 这种dialog有多种多样,其中比较常见的是loading的时候,显示的一个loading进度条. Android显示这样的进度条还是非常方便的,因为有现成的模块可以调用. 首先看看本程序的效果吧: 1 主界面: 2 点击这个按钮之后,显示: 进度条到了100的时候就会自动关闭,当然这里是模拟下载,真实的下载算法还需要继续完善,不过也是很简单的算法了,不算是难点. 点击Cancel或者OK按钮也可以调用函数,进行有需要的操作,这里直接显示一个Toast

Android百日程序: Activity的生命期

到了Android 4 的activity的生命期内的函数有7个,变得十分复杂,完善.故此要掌握好Activity的各个函数,知道应该在那个函数写什么逻辑代码. 本篇博客写个小程序测试一下activity的声明周期如何运作. 首先总结一下: 1 onCreate():activyt第一次创建的时候调用,还可能在改activity在onStop或者onPauce状态下被系统自动释放,那么当用户需要继续回到改activity的时候,也会调用这个onCreate()函数 2 onStart():当改a