« GC 対策 | メイン | サムネイルを読み込みつつ表示する »

2011年02月04日

Android:: 任意の画像を読み込めるようにする(ロード時の画像縮小)

    

任意の画像を読み込めるようにすると、とたんに OutOfMemoryError 例外が出て落ちる。
特にカメラフォルダの中の画像を読み込もうとしたらすぐに落ちる。
そこで読み込む時はまず大きさだけ読み込んで、大きすぎた場合は縮小されたものを読み込む。

private Bitmap getImage( String fullPath ) {
    // まずは大きさだけ得る
    BitmapFactory.Options bmOpt = new BitmapFactory.Options();
    bmOpt.inJustDecodeBounds = true;
    BitmapFactory.decodeFile( fullPath, bmOpt );
    int width = bmOpt.outWidth;
    int height = bmOpt.outHeight;
    // 表示対象の大きさ
    int w = getWidth();
    int h = getHeight();
    if( width > (w*2) || height > (h*2) ) {
        // 大きすぎる(2倍以上の)時は、どちらがより大きいか計算
        int scaleW = width / (w*2);
        int scaleH = height / (h*2);
        int scale = Math.max(scaleW, scaleH);
        bmOpt.inJustDecodeBounds = false;
        bmOpt.inSampleSize = scale;  // 1 / scale の大きさの画像を得る
        return BitmapFactory.decodeFile( fullPath, bmOpt );
    } else {
        return BitmapFactory.decodeFile( fullPath );
    }
}

ある程度の大きさで読み込んだら、次に欲しいサイズに縮小する。

int width = bmp.getWidth();
int height = bmp.getHeight();
int w = getWidth();
int h = getHeight();
float scaleWidth = (float)width / (float)w;
float scaleHeight = (float)height / (float)h;
float scale;
if( scaleWidth > scaleHeight ) {
    // 横の方が大きすぎる
    scale = 1.0f / scaleWidth;
} else {
    scale = 1.0f / scaleHeight;
}
Matrix matrix = new Matrix();
matrix.postScale( scale, scale );
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap( bmp, 0, 0, width, height, matrix, true);

元々ちょうどのサイズならそのまま読めばいい。



投稿者 Takenori : 2011年02月04日 23:46




comments powered by Disqus
Total : Today : Yesterday : なかのひと