Android图形图像处理之Bitmap和BitmapFactory



首先我们来看android.graphics,API是这样说的Provides low level graphics tools such as canvases, color filters, points, and rectangles that let you handle drawing to the screen directly. 意思就是一个低级的画图工具譬如直接把canvases, color filters, points, and rectangles绘制在你的屏幕上。

我们的Bitmap和BitmapFactory就是在这个包中的.Bitmap代表一张位图,BitmapDrawable中封装的图片就是一个Bitmap对象。开发者如果为了把一个Bitmap对象封装成为BitmapDrawable,可以调用BitmapDrawable构造器:

BitmapDrawable bd = new BitmapDrawable(bitmap);

如何需要获取BitmapDrawable的Bitmap对象,则可以调用getBitmap()方法


Bitmap bitmap = BitmapDrawable.getBitmap();

关于Bitmap详细简介,请查看官方API  http://developer.android.com/reference/android/graphics/Bitmap.html


其中Bitmap提供了一些静态方法来创建新的Bitmap对象,例如如下常用方法:

createBitmap(Bitmap source, int x, int y, int width, int height):从源位图的(x,y)开始挖取width*heigth的大小,创建新的Bitmap对象

createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter):从源位图的(x,y)开始挖取width*heigth的大小,创建新的Bitmap对象.并按照Matrix制定的规则进行变换。

createBitmap(int width, int height, Bitmap.Config config):创建一个width*height的新位图

createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter):对源位图进行缩放,缩放后的大小为dstWidth*dstHeight.


BitmapFactory是一个工具类,它提供了大量方法,这些方法可以用于从不同的数据源来解析创建Bitmap对象。

有关BitmapFactory的介绍可以查看http://developer.android.com/reference/android/graphics/BitmapFactory.html

大部分的时候我们只要把图片放到drawable-mdpi目录下,就可以在程序中通过该图片对应的资源ID来获取封装图片的Drawable对象。但是由于手机内存比较小,如果系统不停的去解析、创建Bitmap对象,可能由于前面创建Bitmap所占用的内存还没有回收,从而导致程序运行时引发OutOfMemory错误。

Android为Bitmap提供了如下两个方法来判断它是否已经回收,以及强制Bitmap回收自己。

isRecycled():返回该Bitmap对象是否已经回收。

recycle():强制回收自己。

下面借鉴疯狂Android讲义的一个例子,查看assets目录下的图片

布局代码非常简单,只包含一个Button和一个ImageView


<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button android:text="@string/btn"
        	android:layout_width="wrap_content"
        	android:layout_height="wrap_content"
        	android:layout_alignParentTop="true"
        	android:id="@+id/btn"/>
    <ImageView android:id="@+id/img"
        	   android:layout_width="match_parent"
        	   android:layout_height="match_parent"
        	   android:layout_below="@+id/btn"/>

</RelativeLayout>

Activity文件代码:


package com.example.bitmap;

import java.io.IOException;
import java.io.InputStream;

import android.os.Bundle;
import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

	//使用一个string数组来存储assets目录下的所有文件
	String[] images = null;
	//使用AssetManager来管理assets目录下的资源 
	AssetManager assets = null;
	//当前文件的索引
	int currentItem = 0;
	//屏幕上的ImageView的组件
	ImageView img = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//获取ImageView组件
		img = (ImageView) findViewById(R.id.img);
		
		try {
			//获取AssestManager
			assets = getAssets();
			//获取assets目录下的所有文件
			images = assets.list("");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		//添加事件处理代码
		final Button btn = (Button) findViewById(R.id.btn);
		btn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//如果文件已经遍历完成,则重新开始
				if(currentItem>=images.length)
				{
					currentItem = 0;
				}
				//遍历文件
				while(!images[currentItem].endsWith(".png"))
				{
					currentItem++;
					//遍历完毕
					if(currentItem>=images.length)
					{
						currentItem = 0;
					}
				}
				
				InputStream assetFile = null;
				try {
					//打开图片文件的输入流
					assetFile = assets.open(images[currentItem++]);
					
				} catch (Exception e) {
					e.printStackTrace();
				}
				BitmapDrawable bitmapDrawable = (BitmapDrawable) img.getDrawable();
				//如果图片还未回收,则回收该图片
				if(bitmapDrawable!=null&&!bitmapDrawable.getBitmap().isRecycled())
				{
					bitmapDrawable.getBitmap().recycle();
				}
				//改变ImageView显示的图片
				img.setImageBitmap(BitmapFactory.decodeStream(assetFile));
			}
		});
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}


其实我们可以用Bitmap来实现很多效果,比如说图片放大,图片截取等。BitmapFactory主要的作用就是将资源解析成Bitmap对象


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值