1. 程式人生 > >android影象與影象處理系列(一、Bitmap和BitmapFactory)

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

例項效果如下:點選搜尋下一個,輪換顯示圖片