Переработать растровое изображение ImageView - PullRequest
38 голосов
/ 10 августа 2011

У меня есть что-то вроде этого:

Bitmap.Config conf = Bitmap.Config.ARGB_8888;
WeakReference<Bitmap> bm = new WeakReference<Bitmap>(Bitmap.createBitmap(3000 + 3000, 2000, conf));

Canvas canvas = new Canvas(bm.get());
canvas.drawBitmap(firstBitmap, 0, 0, null);
canvas.drawBitmap(bm, firstBitmap.getWidth(), 0, null);

imageView.setImageBitmap(bm);

И я применяю это к более чем 10 imageView, которые создаются один за другим. Всякий раз, когда я создаю новый ImageView, я хочу перезапустить объект 'bm' из первого, вызвать этот код там, заставить мою кучу расти все больше и больше, а затем выбросить OutOfMemoryError , поэтому я делаю: 1006 *

bm.recycle()

сразу после того, как я установил Bitmap (bm) для объекта imageView. Это вызывает исключение, что холст ImageView хочет нарисовать переработанное растровое изображение.

Как перерабатывать растровое изображение, которое уже было добавлено в ImageView в качестве изображения?

Thanksb

Ответы [ 4 ]

55 голосов
/ 10 августа 2011

В вашем методе onDestroy вы можете попробовать что-то вроде этого:

ImageView imageView = (ImageView)findViewById(R.id.my_image);
Drawable drawable = imageView.getDrawable();
if (drawable instanceof BitmapDrawable) {
    BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
    Bitmap bitmap = bitmapDrawable.getBitmap();
    bitmap.recycle();
}

Приведение должно работать, так как setImageBitmap реализован как

public void setImageBitmap(Bitmap bm) {
    setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
}
2 голосов
/ 10 августа 2011

Если вы установите один и тот же растровый объект на все ваши ImageView s, он не должен выдавать OutOfMemoryError.По сути, это должно работать:

WeakReference<Bitmap> bm = new WeakReference<Bitmap>(Bitmap.createBitmap(3000 + 3000, 2000, Bitmap.Config.ARGB_8888));

Canvas canvas = new Canvas(bm.get());
canvas.drawBitmap(firstBitmap, 0, 0, null);
canvas.drawBitmap(bm, firstBitmap.getWidth(), 0, null);

imageView1.setImageBitmap(bm.get());
imageView2.setImageBitmap(bm.get());
imageView3.setImageBitmap(bm.get());
imageView4.setImageBitmap(bm.get());
imageView5.setImageBitmap(bm.get());
// ...

Если это не работает, это просто означает, что ваше растровое изображение слишком велико (6000x2000 пикселей составляет около 12 мегабайт, если я правильно рассчитал).Вы можете:

  • уменьшить размер растрового изображения
  • сократить другие элементы, которые используют много памяти
1 голос
/ 16 февраля 2015

Ответ Devconsole великолепен, но вы также можете хранить все растровые объекты в списке, как член вашего класса, и затем циклически перерабатывать их, когда метод действия onDestroy () (или какой-либо другой метод жизненного цикла выпуска компонента, в котором вы используете точечный рисунок).

0 голосов
/ 10 августа 2011

Не создавайте изображения больше, чем вам нужно. Ограничения кучи предназначены для предотвращения зависания и полного захвата ограниченной памяти устройства.

Если вам нужно больше деталей, потому что вы планируете увеличивать масштаб, то повторно визуализируйте эту часть изображения с большей детализацией во время увеличения, исключая части, которые вы не просматриваете.

...