Ответ 1
Вот что я придумал на основе метода getBitmap() из библиотеки уроков, который был удален из старой версии Android. Я сделал некоторые изменения:
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 МБ.
Более дружественным для памяти способом было бы не настраивать scale
, поэтому меньшая растровая карта будет масштабироваться, чтобы соответствовать требуемому размеру. Но это уменьшит качество изображения.