android图像与图像处理系列(一、Bitmap和BitmapFactory)

1、Drawable对象

  Android应用添加了Drawabe资源之后,Android SDK会为这份资源文件在R清单文件中创建一个索引项:R.drawable.file_name,接着我们可以在xml资源文件中通过@drawable/file_name来访问该drawable对象,也可以在java代码中通过R.drawable.file_name来访问该drawable对象,在java代码中R.drawable.file_name只是一个int类型的常量,它只代表了drawable对象的一个id,如果要获取实际的drawable对象,则需要调用Resources的getDrawable(int id)方法来获取。

2、Bitmap与BitmapFactory

    (1)Bitmap代表一张位图,BitmapDrawable里封装的图片就是一个Bitmap对象,开发者为了把一个Bitmap对象封装成BitmapDrawable对象,可以调用BitmapDrawable的构造器:
      把一个Bitmap对象包装成BitmapDrawable对象
      BitmapDrawable drawable = new BitmapDrawable(bitmap);
    (2)如果需要获取BitmapDrawable所包装的Bitmap对象,可以调用BitmapDrawable的getBitmap()方法:
        获取BitmapDrawable对象所包装的Bitmap对象
        Bitmap bitmap = drawable.getBitmap();
   (3)Bitmap提供了一些静态方法来创建新的Bitmap对象: 
        Bitmap.createBitmap(source, x, y, width,height):从源位图source的指定坐标点x,y开始,从中挖取宽width、高height的一块区域,创建新的Bitmap
      Bitmap.createScaledBitmap(src, dstWidth, dstHeight,filter):对源位图src进行缩放,缩成宽dstWidth、高DSTHeight的新位图 
        Bitmap.createBitmap(width,height, config):创建一个宽width、高height的新位图 
        Bitmap.createBitmap(source, x, y,width, height, m,filter):从源位图source的指定坐标点x,y开始,从中挖取宽width、高height的一块区域,创建新的Bitmap
          ,并按照Matrix指定的规则进行变换
  (4)BitmapFactory是一个工具类,他提供了一些方法用于从不同的数据源来解析、创建Bitmap对象:
       BitmapFactory.decodeByteArray(byte[] data, int offset, int length):从指定字节数组的offset位置开始,将长度为length的字节数据解析成Bitmap对象
      BitmapFactory.decodeFile(String pathName):从pathName指定的文件中解析、创建Bitmap对象
      BitmapFactory.decodeFileDescriptor(FileDescriptor fd):用于从FileDescriptor对应的文件中解析、创建Bitmap对象
      BitmapFactory.decodeResource(Resources res, int id):用于根据给定的资源ID从指定资源文件中解析、创建Bitmap对象 
        BitmapFactory.decodeStream(InputStream is):用于从指定输入流中解析、创建Bitmap对象
  (5)Android为Bitmap提供了两个方法来判断它是否已经回收,以及强制Bitmap回收自己
      isRecycled():判断Bitmap对象是否已经回收
       recycle():强制一个Bitmap对象立即回收自己

3、实例:图片查看器,查询assets目录下的图片

布局文件:

<LinearLayout 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:orientation="vertical"
    android:gravity="center" >

    <ImageView
        android:id="@+id/imageview"
        android:layout_width="300dp"
        android:layout_height="300dp" />

    <Button
        android:id="@+id/btn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="搜索下一个" />

</LinearLayout>

activity文件:

package com.example.image;

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

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

/**
 * Bitmap和BitmapFactory
 * @author yinbenyang
 */
public class MainActivity extends Activity {

    private ImageView imageview;
    String[] images = null;
    private Button btn;
    // 用于管理assets文件夹下的资源
    AssetManager assets = null;
    // 当前图片
    int currentImg = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageview = (ImageView) findViewById(R.id.imageview);
        btn = (Button) findViewById(R.id.btn);
        assets = getAssets();
        try {
            // 获取/assets目录下的所有文件
            images = assets.list("");
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 点击按钮查看下一张图片
        btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //如果图片是最后一个了,就置为第一个
                if (currentImg >= images.length) {
                    currentImg = 0;
                }
                //找到下一个图片文件
                while (!images[currentImg].endsWith(".png")
                        && !images[currentImg].endsWith(".jpg")
                        && !images[currentImg].endsWith(".gif")) {
                    currentImg++;
                    if (currentImg >= images.length) {
                        currentImg = 0;
                    }
                }
                InputStream assetFile = null;
                try {
                    //打开指定资源对应的输入流
                    assetFile = assets.open(images[currentImg++]);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                BitmapDrawable bitDrawable = (BitmapDrawable)imageview.getDrawable();
                //如果图片没有回收,先强制回收该图片
                if(bitDrawable != null && !bitDrawable.getBitmap().isRecycled()){
                    bitDrawable.getBitmap().recycle();
                }
                //改变ImageView显示的图片
                imageview.setImageBitmap(BitmapFactory.decodeStream(assetFile));
            }
        });
    }
}

实例效果如下:点击搜索下一个,轮换显示图片

android图像与图像处理系列(一、Bitmap和BitmapFactory)android图像与图像处理系列(一、Bitmap和BitmapFactory)android图像与图像处理系列(一、Bitmap和BitmapFactory)