2012年3月1日木曜日

[Android] 端末内の画像を読み込みViewに合わせて回転・縮小する

現在開発中のAndroidアプリで端末内の画像をBitmapとして読み込む際に、回転や縮小といった処理を実装したのでそのことについて書きたいと思います。

今回のコードで行なっていることは以下の4つです。
  1. 端末内の画像のUriを取得
  2. Uriから画像データをBitmapとして読み込み
  3. Exifの回転情報を反映
  4. BitmapをセットするViewに合わせてサイズを縮小

まず端末内の画像を選択しそのUriを取得する部分ですが、これは以下の方法が非常に便利でした。

【Android】Galleryを使ってSDカード内の画像をリスト表示する | cozzbox

        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, 0); 

こうするとonActivityResultのdataにUriが格納されて返ってきます。
画像を選択するGridView等を自前で実装しなくて済むので助かりますね。

続いて得られたUriを用いてBitmapを作成し、回転・縮小する部分(上記の2.~4.の処理)のコードです。

    private Bitmap loadBitmap(Uri uri, int viewWidth, int viewHeight) {
        // Uriから画像を読み込みBitmapを作成
        Bitmap originalBitmap = null;
        try {
            originalBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // MediaStoreから回転情報を取得
        final int orientation;
        Cursor cursor = MediaStore.Images.Media.query(getContentResolver(), uri, new String[] {
            MediaStore.Images.ImageColumns.ORIENTATION
        });
        if (cursor != null) {
            cursor.moveToFirst();
            orientation = cursor.getInt(0);
        } else {
            orientation = 0;
        }

        final int originalWidth = originalBitmap.getWidth();
        final int originalHeight = originalBitmap.getHeight();

        // 縮小割合を計算
        final float scale;
        if (orientation == 90 || orientation == 270) {
            scale = Math.min((float)viewWidth / originalHeight, (float)viewHeight / originalWidth);
        } else {
            scale = Math.min((float)viewWidth / originalWidth, (float)viewHeight / originalHeight);
        }

        // 変換行列の作成
        final Matrix matrix = new Matrix();
        if (orientation != 0) {
            matrix.postRotate(orientation);
        }
        if (scale < 1.0f) {
            matrix.postScale(scale, scale);
        }

        // 行列によって変換されたBitmapを返す
        return Bitmap.createBitmap(originalBitmap, 0, 0, originalWidth, originalHeight, matrix,
                true);
    }

回転情報の取得に関しては、下記の記事を参考にさせて頂きました。

画像の向き(Orientation)を取得 | ゆーすけぶろぐ
ヒビノアワ: andoridでサムネイル画像を正しい向きで表示する


ここでのポイントは、回転方向によって縮小割合の計算の仕方が変わるという点です。
  • 画像が90度, もしくは270度(横向き)の場合
    →Viewの幅と画像の高さ、Viewの高さと画像の幅の割合を計算
  • 上記以外(縦向き)の場合
    →Viewの幅と画像の幅、Viewの高さと画像の高さの割合を計算

Bitmapの貼り付け先としてImageViewを用いず、自前でCanvasに描画する場合などに使えるかなと思いますので、もしよければ参考にしてみてください。

0 件のコメント:

コメントを投稿