Масштабирование изображений в Android вызывает исключение OutOfMemory - PullRequest
1 голос
/ 28 мая 2011

Я разрабатываю игру для Android, состоящую из множества изображений в виде спрайтов.

Когда я загружаю изображения следующим образом:

public static Bitmap loadBitmap(int resId) {  
    return BitmapFactory.decodeResource(getResources(), resId, options);
}

все отлично работает.

Когда я пытаюсь уменьшить или увеличить растровое изображение с помощью этого кода:

public static Bitmap loadBitmap(int resId) {
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId, options);
    Matrix matrix = new Matrix();
    matrix.postScale(0.8f, 0.8f);
    Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    bitmap.recycle();
    bitmap = null;
    return scaledBitmap;
}

приложение вылетает со следующим исключением:

2211840-byte external allocation too large for this process.  
Out of memory: Heap Size=4935KB, Allocated=2549KB, Bitmap Size=18463KB  
VM won't let us allocate 2211840 bytes

Почему масштабирование вызывает исключение OutOfMemory? Я даже пытаюсь переработать исходное изображение, чтобы сэкономить место. Я не использую Bitmap.createScaledBitmap(...) намеренно, так как этот метод вызывает внутреннюю утечку памяти (как объяснено в других сетевых ресурсах).

Заранее спасибо,
Златко

Ответы [ 3 ]

1 голос
/ 28 мая 2011

Вы, вероятно, просто очень близки к пределу памяти. Похоже, вы создаете довольно большое растровое изображение (и я не уверен, почему вы делаете его такого же размера, как исходное растровое изображение). Исходя из журнала, вы использовали 25 МБ выделений Java и 18 МБ выделений растровых изображений, так что вы, по сути, оказались на уровне предела кучи в 48 МБ.

Также я думаю, что очень маловероятно, что createScaledBitmap () протекает. Все, что он делает, это то, что ты здесь делаешь.

0 голосов
/ 28 мая 2011

Полагаю, вы действительно близки к пределу кучи. В своей функции вы в основном создаете экземпляр второго битмапа, что примерно приводит к удвоению вашей памяти (битмапы очень большие). Если вы используете ОС раньше, чем Honeycomb, также неверно смотреть на значения памяти, которые где-то распечатываются. iirc, битовые карты хранятся непосредственно в куче системной памяти, тогда как все остальное хранится в куче виртуальной машины (и это значения, которые вы видите -> 2,5 МБ). Однако память для выделения растровых изображений также учитывает ограничение кучи памяти. : /

Я предлагаю вам взглянуть на эту сессию ввода-вывода Google: http://www.youtube.com/watch?v=_CruQY55HOk

Я думаю, что ваша проблема может быть решена только путем снижения разрешения вашего Bitmap или с помощью некоторой функции масштабирования, которая не создает экземпляр нового Bitmap и модифицирует существующее (например, упомянутое AmandeepGrewal).

0 голосов
/ 28 мая 2011

Вы должны попытаться использовать переменную "inSampleSized" в классе BitmapFactory.Options.Это будет масштабироваться без использования избыточной памяти.

http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize

...