How to load large images in Android and avoiding the out of memory error?

后端 未结 6 2013
梦谈多话
梦谈多话 2020-12-01 08:05

I\'m working on an app that uses large images (1390 × 870 : 150kb - 50kb). I\'m adding images as I tap a trigger/ImageView.

At a certain point I\'m getting an out of

相关标签:
6条回答
  • 2020-12-01 08:44

    Use Fresco library to load large images will avoid this error. in xml layout

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/my_image_view"
        android:layout_width="1300dp"
        android:layout_height="1300dp"
        fresco:placeholderImage="@drawable/my_drawable"
      />
    

    and in javacode

    Uri uri = Uri.parse("https://image.png");
    SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);
    draweeView.setImageURI(uri);
    
    0 讨论(0)
  • 2020-12-01 08:45

    You can use this beautiful library https://github.com/davemorrissey/subsampling-scale-image-view

    0 讨论(0)
  • 2020-12-01 08:47

    You are still going to need to manage the bitmap memory as I wouldn't try to allocate a total space more than 3x the size of the screen (if you think about it makes sense for scrolling behavior). If you are overlaying one image on top of another, at some point, you're hitting an Out Of Memory error. You may need to look at capturing the prior screen image as a single background image to make sure you still fit within the available memory. Or when a new image overlaps an existing image only load and render the visible portion. If performance becomes an issue, then you may need to consider OpenGL Textures but the memory allocation problem is still the same.

    Do go through all of the Displaying Bitmaps Training as it should give you some additional ideas of how to handle display.

    0 讨论(0)
  • 2020-12-01 08:50

    Here is how I'm adding each item to the FrameLayout that's the problem, the code keep adding and adding more images, and doesn't matter how well you resize or how much memory the device have, at certain point it WILL run out of memory. That's because every image you add it's keeping in memory.

    For this type of situation what the apps do is to use a ViewGroup that can recycle views. I don't know your layout, but usually is a ListView, GridView or a ViewPager, by recycling views you re-use the layout and can dispose re-load images as necessary.

    For the specific purpose of loading and resizing images I strongly advise use Picasso library as it is VERY well written, simple to use and stable.

    0 讨论(0)
  • 2020-12-01 09:06

    High resolution devices such as S4 usually run out of memory if you do not have your image in the proper folder which is drawable-xxhdpi. You can also put your image into drawable-nodpi. The reason it would run out of memorey if your image just in drawable that the android would scale the image thinking that the image was designed for low resolution.

    0 讨论(0)
  • 2020-12-01 09:10

    You can use another bitmap-config to heavily decrease the size of the images. The default is RGB-config ARGB8888 which means four 8-bit channels are used (red, green, blue, alhpa). Alpha is transparency of the bitmap. This occupy a lot of memory - imagesize X 4. So if the imagesize is 4 megapixel 16 megabytes will immidiately be allocated on the heap - quickly exhausting the memory.

    Instead - use RGB_565 which to some extent deteriorate the quality - but to compensate this you can dither the images.

    So - to your method decodeSampledBitmapFromResource - add the following snippets:

     options.inPreferredConfig = Config.RGB_565;
     options.inDither = true;
    

    In your code:

     public static Bitmap decodeSampledBitmapFromResource(Resources res, String resId, int    reqWidth, int reqHeight) {
    
     // First decode with inJustDecodeBounds=true to check dimensions
     final BitmapFactory.Options options = new BitmapFactory.Options();
     options.inJustDecodeBounds = true;
     BitmapFactory.decodeFile(resId, options);
    
     // Calculate inSampleSize
     options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
     // Decode bitmap with inSampleSize set
     options.inJustDecodeBounds = false;
     options.inPreferredConfig = Config.RGB_565;
     options.inDither = true;
     return BitmapFactory.decodeFile(resId, options);
     }
    

    References:

    http://developer.android.com/reference/android/graphics/Bitmap.Config.html#ARGB_8888

    0 讨论(0)
提交回复
热议问题