これは、古い Android バージョンから削除されたクロップ ライブラリの getBitmap() というメソッドに基づいて、私が思いついたものです。私はいくつかの変更を行いました:
private Bitmap getBitmap(Uri uri, int width, int height) {
InputStream in = null;
try {
int IMAGE_MAX_SIZE = Math.max(width, height);
in = getContentResolver().openInputStream(uri);
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, o);
in.close();
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
//adjust sample size such that the image is bigger than the result
scale -= 1;
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
in = getContentResolver().openInputStream(uri);
Bitmap b = BitmapFactory.decodeStream(in, null, o2);
in.close();
//scale bitmap to desired size
Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, width, height, false);
//free memory
b.recycle();
return scaledBitmap;
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
return null;
}
これが行うことは、BitmapFactory.Options() + いくつかのサンプル サイズを使用してビットマップをロードすることです。この方法では、元の画像はメモリにロードされません。問題は、サンプルサイズが段階的に機能することです。コピーした数学を使用して画像の「最小」サンプルサイズを取得し、最小値を生成するサンプルサイズを取得するために1を減算します。必要なサイズよりも大きいビットマップ。
そして、正確に要求されたサイズのビットマップを取得するために、 で通常のスケーリングを行いBitmap.createScaledBitmap(b, width, height, false);
ます。そしてすぐに、より大きなビットマップをリサイクルします。たとえば、私の場合、480 x 800 のビットマップを取得するために、より大きなビットマップは 1280 x 960 であり、4.6 MB のメモリを占有するため、これは重要です。
よりメモリに優しい方法は、調整しないことscale
です。したがって、より小さいビットマップが必要なサイズに合わせて拡大されます。しかし、これは画像の品質を低下させます。