Android图形图像处理之Bitmap和BitmapFactory

来源:互联网 发布:软件通用质量特性 编辑:程序博客网 时间:2024/05/01 00:16


首先我们来看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;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//获取ImageView组件img = (ImageView) findViewById(R.id.img);try {//获取AssestManagerassets = getAssets();//获取assets目录下的所有文件images = assets.list("");} catch (IOException e) {e.printStackTrace();}//添加事件处理代码final Button btn = (Button) findViewById(R.id.btn);btn.setOnClickListener(new OnClickListener() {@Overridepublic 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));}});}@Overridepublic 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对象