2012年7月2日

【Android】GallaryからBitmapを取得する


画像をGallaryから取得しようとしたら重すぎて落ちた。
どうしようどうしようと悩んでも仕方がないので、
いろいろ検索して、画像サイズを小さくすれば良いと
なんとか解決に至ったので、その方法を書いておきます。



まずはGallaryから画像の取得。
Constsは定数だけまとめてあるクラスです。

// start activity
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,
  Consts.INTENT_REQUEST_SEND_PICTURE);

これでGallaryが立ち上がります。

選択した画像はonActivityResultで受け取りましょう。

public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if(requestCode == Const.INTENT_REQUEST_SEND_PICTURE 
      && resultCode == Activity.RESULT_OK) {
    // 戻り値からInputStreamを取得
    InputStream in = getContentResolver().openInputStream(data.getData());
    // Bitmapの取得
    Bitmap bitmap = BitmapFactory.decodeStream(in);
  }
}

ちなみに、このままではBitmapを取得するところでアプリが落ちます。
画像ファイルが重すぎて読み込めない為で、Androidのメモリでは足りません。

では、どうやって対策するかといいますと、
読み込む前に画像サイズをリサイズしてしまえば良いのです。

という訳でonActivityResultその2

public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if(requestCode == Const.INTENT_REQUEST_SEND_PICTURE 
      && resultCode == Activity.RESULT_OK) {
    // 戻り値からInputStreamを取得
    InputStream in = getContentResolver().openInputStream(data.getData());
    // 読み込む際のオプション
    BitmapFactory.Options options = new BitmapFactory.Options();
    // 画像を読み込まずサイズを調整するだけにする
    options.inJustDecodeBounds = true;
    // optionsに画像情報を入れる
    BitmapFactory.decodeStream(in, null, options);
    // InputStreamは1回クローズする(もう中身が無い為、再利用は出来無い)
    in.close();
    // Displayに収まるサイズに調整するための割合を取得
    int width = options.outWidth / displayWidth + 1;
    int height = options.outHeight / displayHeight + 1;
    // 画像を 1 / Math.max(width, height) のサイズで取得するように調整
    options. inSampleSize = Math.max(width, height);
    // 実際に画像を読み込ませる
    options.inJustDecodeBounds = false;
    // もう1回InputStreamを取得
    in = getContentResolver().openInputStream(data.getData());
    // Bitmapの取得
    Bitmap bitmap = BitmapFactory.decodeStream(in, null, options);
    // InputStreamのクローズ
    in.close();
  }
}

と、長くなってしまいましたが、
これで落ちる事はなくなりました。
画像もちょうどよいサイズに調整され読み込まれているように思います。