2013-05-21 2 views
1

У меня возникли OutOfMemoryError в моем VSD220 (это 22" Android на основе все в одном)Android Bitmap OutOfMemoryError

for (ImageView img : listImages) { 
      System.gc(); 

      Bitmap myBitmap = BitmapFactory.decodeFile(path); 
      img.setImageBitmap(myBitmap); 
      img.setOnClickListener(this); 
     } 

Я действительно не знаю, что делать, потому что это изображение ниже максимума разрешение. размер изображения кое-что о (1000x1000), и на дисплее это 1920х1080.

Любая помощь? (это Еогеасп цикл в течение приблизительно 20 элементов, она Гоц сломана после 6 или 7 петель ..)

Большое спасибо.

Ezequiel.

+0

Я не согласен с обозначением этого как дубликата. В этом вопросе одно и то же изображение повторно загружается в цикл. Даже если изображение будет очень маленьким, вы получите ошибку из памяти, если количество итераций достаточно велико. – britzl

ответ

0

Вы действительно уверены, что хотите загрузить тот же Bitmap 20 раз? Вы не хотите загружать его один раз и устанавливать его внутри цикла.

Тем не менее, загрузка изображения размером 1000x1000 пикселей не гарантируется, независимо от разрешения экрана. Помните, что изображение размером 1000х1000 пикселей занимает 1000х1000х4 байта = ~ 4 МБ (если вы загружаете его как ARGB_8888). Если ваша память кучи фрагментирована/слишком мала, у вас может не хватить места для загрузки растрового изображения. Вы можете посмотреть в BitmapFactory.Options класс и экспериментировать с inPreferredConfig и inSampleSize

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

/** 
* Load a bitmap from a stream using a specific pixel configuration. If the image is too 
* large (ie causes an OutOfMemoryError situation) the method will iteratively try to 
* increase sample size up to a defined maximum sample size. The sample size will be doubled 
* each try since this it is recommended that the sample size should be a factor of two 
*/ 
public Bitmap getAsBitmap(InputStream in, BitmapFactory.Config config, int maxDownsampling) { 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inSampleSize = 1; 
    options.inPreferredConfig = config; 
    Bitmap bitmap = null; 
    // repeatedly try to the load the bitmap until successful or until max downsampling has been reached 
    while(bitmap == null && options.inSampleSize <= maxDownsampling) { 
     try { 
      bitmap = BitmapFactory.decodeStream(in, null, options); 
      if(bitmap == null) { 
       // not sure if there's a point in continuing, might be better to exit early 
       options.inSampleSize *= 2; 
      } 
     } 
     catch(Exception e) { 
      // exit early if we catch an exception, for instance an IOException 
      break; 
     } 
     catch(OutOfMemoryError error) { 
      // double the sample size, thus reducing the memory needed by 50% 
      options.inSampleSize *= 2; 
     } 
    } 
    return bitmap; 
} 
+0

Извините, я не хочу загружать одно и то же изображение 20 раз, я хотел упростить пример, мой настоящий код состоит из массива путей. Таким образом, изображение не то же самое, но размеры. Я пытаюсь ваши ответы прямо сейчас, ребята. Я еще раз прокомментирую это. спасибо! –

+0

Спасибо вам обоим. Он работал на эти миниатюры, теперь мне нужно отобразить полноэкранное изображение (в данном случае, 1920x1024) и создать галерею из них. Я попытаюсь сделать это, прочитав раздел растрового изображения андроида! http://developer.android.com/training/displaying-bitmaps/index.html –

1

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

В частности, вы, вероятно, придется использовать измененную версию кода в «Load a Scaled Down Version into Memory», но я по крайней мере, нашел этот раздел особенно полезным:

public static int calculateInSampleSize(
      BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     // Calculate ratios of height and width to requested height and width 
     final int heightRatio = Math.round((float) height/(float) reqHeight); 
     final int widthRatio = Math.round((float) width/(float) reqWidth); 

     // Choose the smallest ratio as inSampleSize value, this will guarantee 
     // a final image with both dimensions larger than or equal to the 
     // requested height and width. 
     inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
    } 

    return inSampleSize; 
} 



public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
     int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeResource(res, resId, options); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeResource(res, resId, options); 
} 

Этот Способ позволяет легко загружать растровое изображение произвольно большого размера в ImageView, который отображает 100x100 пикселей, эскиз, как показано на следующий пример кода:

mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100)); 
+0

try { // Код здесь, который вызывает OutOfMemoryError } catch (Error ee) { \t ee.printStacktrace(); } –

Смежные вопросы