0

I recently ran into some OutOfMemory error in an android application I am working on, mostly because I am loading the images in their original size (now I know this is a bad idea).

Im now working on implementing methods to load scaled down versions of the images depending on the actual ImageView size and caching them as suggested in googles developer guide.

The guide states out very well how I should process and handle images loaded at runtime in Java code, but it leaves out how to work with images defined via XML in my layout files. For example if I have an ImageView with a predefined Image, the XML code would look something like this:

 <ImageView
        android:id="@+id/my_image_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/my_image"
         />

If I now want to replace that image at runtime, im checking the width and height of the ImageView, and load the new image according to these dimensions:

imageView.setImageBitmap(decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight)

Obviously, this has not be done for the Image defined via XML. Do I have to worry about these images, too, or does the system handle the downscaling for them? Or should I avoid declaring the src of an imageview via XML at all?

Thanks in advance, danijoo

6
  • This code is ok. Predefined src for imageview - is normal way and setImageBitmap works good. I think the problem in your decodeSampledBitmapFromResource method or imageView variable is not properly initialized. Commented Nov 22, 2013 at 12:04
  • I dont have a problem with the code above. I just want to understand what android is doing with images loaded directly via XML. Are they loaded in there "large" scale or downscaled by default. And are they recycled properly? Commented Nov 22, 2013 at 12:08
  • what android is doing will most likely depend on the version. I vaguely remember they did something about these (or maybe not these but similar) things. Commented Nov 22, 2013 at 12:12
  • problem is in decodeSampledBitmapFromResource() method can you post it ? Commented Nov 22, 2013 at 12:17
  • You can take a look at the Android source code here. It seems that it strongly depends on the ImageView dimensions, but I didn't find the point where the resources is loaded, yet. The answer is somewhere there. ;) Commented Nov 22, 2013 at 12:20

2 Answers 2

1

When you set in an image from your drawable folder android does take care for you. But in that case you have to help too :) . For example if you only provide an image for drawable-mdpi and you do run your application in hpdi devices android will scale up the image to fit it in the screen.But of course before it does it will try to find hdpi version of that image into drawable-hdpi folder. If you do provide hdpi version of that image into drawable-hdpi folder it will not scale.

Now as for your OutOfMemoryError i think you might've put your image in only drawable or any of the low dpi folder and you haven't put that image's larger version to other high dpi folders.(hdpi/xhdpi/xxhdpi).

As per documentation:

Provide different bitmap drawables for different screen densities: By default, Android scales your bitmap drawables (.png, .jpg, and .gif files) and Nine-Patch drawables (.9.png files) so that they render at the appropriate physical size on each device. For example, if your application provides bitmap drawables only for the baseline, medium screen density (mdpi), then the system scales them up when on a high-density screen, and scales them down when on a low-density screen.

I think you will find more useful information in :screens_support

Sign up to request clarification or add additional context in comments.

4 Comments

I think danijoos question is slightly different. For your example, imagine you only have the picture in the xhdpi folder and of course the picturehas the resolution required for such devices. Now you want to use this image for ldpi devices. If Android doesn't scale down it it might imply an out-of-memory on this devices, as there is no ldpi version available. Somebody here able to test this?
@Baschi I might have been wrong but as far as i know android does take care of it too :) as i found in documentation and from my experience : "For example, if your application provides bitmap drawables only for the baseline, medium screen density (mdpi), then the system scales them up when on a high-density screen, and scales them down when on a low-density screen.". You will find it in developer.android.com/guide/practices/screens_support.html
@Baschi thats exactly what i want to know! :)
@danijoo i might've misunderstood, are you asking the same question that Baschi commented on my answer? To answer this yes android does scale down the image when you have that image in xhpdi folder and you are trying to run it on hdpi/mdpi/ldpi device. "scales them down when on a low-density screen."
0

Use below code to scale down size of image when you are selecting it from Gallery or Camera.

       Intent photoPickerIntent = new Intent(
                        Intent.ACTION_PICK,
                                     android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                // photoPickerIntent.setType("image/*");
                photoPickerIntent.putExtra("crop", "true");
                photoPickerIntent.putExtra("outputX", 512);
                photoPickerIntent.putExtra("outputY", 512);
                photoPickerIntent.putExtra("aspectX", 1);
                photoPickerIntent.putExtra("aspectY", 1);
                photoPickerIntent.putExtra("scale", true);

This will load image of required size into your app and system will not run out of memory.

You can ask if you have any further queries.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.