2012-12-24 3 views
1

возникли проблемы с обработкой java.lang.OutOfMemoryError: размер растрового изображения превышает бюджетную ошибку VM. Исходные фотографии никогда не больше 250x250px. и загружается из выпадающей папки. Я нашел некоторые решения в Интернете, говорящие о «inJustDecodeBounds», но я просто не могу заставить его работать. Любые идеи о том, как исправить эту проблему? Это вызывает у меня головная боль в течение двух дней теперь ...OutOfMemoryError при загрузке моего gridview с изображениями

Сейчас я масштабирование изображения на фактор, который я вычисляю на основе материнской ширине ..

@Override 
    public View getView(int position, View v, ViewGroup parent) { 
     View mView = v; 
     this.parent = parent; 

     if (mView == null) { 

      LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
        Context.LAYOUT_INFLATER_SERVICE); 
      mView = vi.inflate(R.layout.caa_xml, null); 
     } 

     ImageView image = (ImageView) mView.findViewById(R.id.iv_caarow); 

     String name = getItem(position).getFile(); 
     int resId = C.getResources().getIdentifier(name, "drawable", 
       "com.test.com"); 
     int imageWidth = (int) calculateImageWidth(); 
     // load the origial BitMap (250 x 250 px) 
     Bitmap bitmapOrg = BitmapFactory 
       .decodeResource(C.getResources(), resId); 

     int width = bitmapOrg.getWidth(); 
     int height = bitmapOrg.getHeight(); 
     int newWidth = imageWidth; 
     int newHeight = imageWidth; 

     float scaleWidth = ((float) newWidth)/width; 
     float scaleHeight = ((float) newHeight)/height; 

     // create a matrix for the manipulation 
     Matrix matrix = new Matrix(); 
     // resize 
     matrix.postScale(scaleWidth, scaleHeight); 
     // recreate the new Bitmap 
     Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, width, 
       height, matrix, true); 

     BitmapDrawable bmd = new BitmapDrawable(resizedBitmap); 

     image.setImageDrawable(bmd); 

     if (mView != null) { 

      //additional code here 

     } 
     return mView; 
    } 

    private float calculateImageWidth() { 
     // TODO Auto-generated method stub 
     int parentW = parent.getWidth() - parent.getPaddingLeft() 
       - parent.getPaddingRight(); 
     Resources r = C.getResources(); 
     float pxPaddingBetweenItem = TypedValue.applyDimension(
       TypedValue.COMPLEX_UNIT_DIP, 2, r.getDisplayMetrics()); 
     float pxPaddingInItem = TypedValue.applyDimension(
       TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics()); 

     int totalImageWidth = (parentW - (int) (3 * pxPaddingBetweenItem) - (int) (8 * pxPaddingInItem))/4; 
     float imageWidth = (float) totalImageWidth; 
     return imageWidth; 
    } 

ответ

3

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

Во всяком случае, есть лучший способ:

ImageView imageView = (ImageView) findViewById(R.id.some_id); 
String pathToImage = "path"; 

BitmapFactory.Options bmOptions = new BitmapFactory.Options(); 
bmOptions.inJustDecodeBounds = true; 
BitmapFactory.decodeFile(pathToImage, bmOptions); 
int photoW = bmOptions.outWidth; 
int photoH = bmOptions.outHeight; 

// Determine how much to scale down the image 
int scaleFactor = Math.min(photoW/50, photoH/50); 

// Decode the image file into a Bitmap sized to fill the View 
bmOptions.inJustDecodeBounds = false; 
bmOptions.inSampleSize = scaleFactor; 
bmOptions.inPurgeable = true; 

Bitmap bitmap = BitmapFactory.decodeFile(pathToFile, bmOptions); 
imageView.setImageBitmap(bitmap); 

Edit:

Если вы хотите использовать идентификатор ресурса вместо пути к файлу, используйте decodeResource и сделать последнюю часть, как это :

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceId, bmOptions); 
imageView.setImageBitmap(bitmap); 

Надеюсь, что этот фрагмент кода поможет вам!

+0

Спасибо Крису! Только один вопрос, путь, мне нужно получить его в строке? Или можно получить это с помощью int resId = C.getResources(). GetIdentifier (имя, «drawable», \t \t \t \t «com.test.com»); и использовать decodeFile (resId, ...)? –

+1

Отредактировано мое сообщение - надежда, которая поможет вам! Если да, отметьте пост как правильный ответ, это Рождество;) –

+0

Эй, Крис, я обязательно это сделаю;) Он работает сейчас! У меня только большая потеря качества .. особенно края с этим методом .. Я нашел на SA, что добавление bmOptions.inScaled = false; \t \t bmOptions.inDither = false; \t \t bmOptions.inPreferredConfig = Bitmap.Config.ARGB_8888; решила бы это, но это doesens't ...: s –

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