BitmapRegionDecoderクラスで画像を切り出す


Android SDK 2.3.3(API レベル10)からBitmapRegionDecoderクラスが追加されました。

BitmapRegionDecoderクラスは用意した画像(JPEG形式,PNG形式)を任意の矩形で切り抜いてBitmapクラスを取得することができます。

それでは続きへどうぞ

BitmapFactoryクラス

まずは今までと同じ方法で読み込んでみます。画像ファイルを読み込んでBitmapクラスを生成するにはBitmapFactoryクラスのdecodeFileメソッドやdecodeResourceメソッドを利用します。

File file = Environment.getExternalStorageDirectory();
ImageView imageView = (ImageView)findViewById(R.id.imageView);
Bitmap bitmap = BitmapFactory.decodeFile(file.toString() + "/sample.png");
imageView.setImageBitmap(bitmap);

上記のソースではSDカード上のPNGファイルを読み込んでImageViewに張り付けています。

元画像をそのまま表示することになるのでこのようになります。

BitmapRegionDecoderクラス

では本題の切り出しを行いましょう。BitmapRegionDecoderクラスを利用します。繰り返しになりますが切り出す元画像としてはJPEG形式とPNG形式に限られます

newInstanceメソッド

BitmapRegionDecoderクラスのインスタンスはnew演算子で生成するのではなく、newInstanceメソッドで生成します。

static BitmapRegionDecoder	 newInstance(String pathName, boolean isShareable)
static BitmapRegionDecoder	 newInstance(InputStream is, boolean isShareable)
static BitmapRegionDecoder	 newInstance(FileDescriptor fd, boolean isShareable)
static BitmapRegionDecoder	 newInstance(byte[] data, int offset, int length, boolean isShareable)

それぞれ、第1引数には(Byte配列だけは第2,3引数も)BitmapFactoryクラスを使う時の以下のメソッドと同じ物を指定します。

  • decodeFile
  • decodeStream
  • decodeFileDescriptor
  • decodeByteArray

第2引数(Byte配列の場合は第4引数)のisShareableをfalseにするとBitmapRegionDecoderクラスは入力データをコピーします。isShareableをtrueにするとコピーせずに入力データへの参照を持つため消費メモリは減りますが、プログレッシブJPEGの場合にデコード速度が低下する可能性があります。

decodeRegionメソッド

newInstanceメソッドでBitmapRegionDecoderクラスのインスタンスを生成したらdecodeRegionメソッドで任意の矩形のBitmapを取得します。

Bitmap	 decodeRegion(Rect rect, BitmapFactory.Options options)

第1引数で切り抜きたい矩形の座標を指定します。

第2引数はこちらはBitmapFactoryクラスのdecodeFileメソッドの第2引数と同様に縮小するなどのオプションを指定します。
※不要な場合はnullを指定。inPurgeableは未サポート

サンプルソース

File file = Environment.getExternalStorageDirectory();
ImageView imageView = (ImageView)findViewById(R.id.imageView);
try {
	BitmapRegionDecoder regionDecoder;
	regionDecoder = BitmapRegionDecoder.newInstance(file.toString() + "/sample.png",
																		false);
    Rect rect = new Rect(0, 0, 150, 150);
    Bitmap bitmap = regionDecoder.decodeRegion(rect, null);
    imageView.setImageBitmap(bitmap);
} catch (IOException e) {
	e.printStackTrace();
}

上記のコードでは左上(0,0)から縦横150ピクセルの矩形で元画像を切り抜いてBitmapクラスを取得しています。

元画像が300×300なのでちょうど左上4分の1を切り取って表示する形となっています。