5
<ImageView
    android:id="@+id/bg"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:adjustViewBounds="true"
    android:scaleType="centerCrop"
    android:src="@drawable/bg" />

@drawable/bg is 1600 * 1800 (W * H)

I tried using

BitmapFactory.decodeResource(getResources(), R.drawable.bg, options);

using inSampleSize

Here are the logs:

02-05 05:32:05.841: E/screenWidth in px =(876): 768
02-05 05:32:05.841: E/screenheight in px =(876): 1184
02-05 05:32:05.841: E/screenDensity =(876): 2.0
02-05 05:32:05.841: E/screenDensityDpi =(876): 320
02-05 05:32:05.841: E/decodeSampledBitmapFromResource reqWidth =(876): 768
02-05 05:32:05.851: E/decodeSampledBitmapFromResource reqHeight =(876): 1184
02-05 05:32:05.921: E/decodeSampledBitmapFromResource imageHeight =(876): 1800
02-05 05:32:05.921: E/decodeSampledBitmapFromResource imageWidth =(876): 1600
02-05 05:32:05.921: E/decodeSampledBitmapFromResource imageType =(876): image/jpeg
02-05 05:32:05.951: E/calculateInSampleSize: inSampleSize =(876): 1
02-05 05:32:09.291: E/dalvikvm-heap(876): Out of memory on a 44441616-byte allocation.
02-05 05:32:09.391: E/AndroidRuntime(876): FATAL EXCEPTION: main
02-05 05:32:09.391: E/AndroidRuntime(876): Process: com.example.splash, PID: 876
02-05 05:32:09.391: E/AndroidRuntime(876): java.lang.OutOfMemoryError
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:587)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:422)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:445)
02-05 05:32:09.391: E/AndroidRuntime(876):  at com.example.splash.SecondActivity.decodeSampledBitmapFromResource(SecondActivity.java:103)
02-05 05:32:09.391: E/AndroidRuntime(876):  at com.example.splash.SecondActivity.onCreate(SecondActivity.java:57)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.app.Activity.performCreate(Activity.java:5231)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.app.ActivityThread.access$800(ActivityThread.java:135)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.os.Handler.dispatchMessage(Handler.java:102)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.os.Looper.loop(Looper.java:136)
02-05 05:32:09.391: E/AndroidRuntime(876):  at android.app.ActivityThread.main(ActivityThread.java:5017)
02-05 05:32:09.391: E/AndroidRuntime(876):  at java.lang.reflect.Method.invokeNative(Native Method)
02-05 05:32:09.391: E/AndroidRuntime(876):  at java.lang.reflect.Method.invoke(Method.java:515)
02-05 05:32:09.391: E/AndroidRuntime(876):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-05 05:32:09.391: E/AndroidRuntime(876):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-05 05:32:09.391: E/AndroidRuntime(876):  at dalvik.system.NativeStart.main(Native Method)

The thing is, for a device which has height 1184 the

inSampleSize will be 1 (Hence no change)

So, its kind of useless going through all this process and the same OOM occurs.

This single screen shows that it takes 44 mb of memory, which I got using:

long totalMem = Runtime.getRuntime().totalMemory();

If I set image src as @null, the above value is 3 mb

Is this a reliable way to find the memory usage by the app?

Please help me how to load such high resolution images without any OOM.

Archie.bpgc
  • 23,812
  • 38
  • 150
  • 226
  • Do you really have to use the whole image? Isn't there something that can be composed from a 9 patch? Can you show the image? – gunar Feb 05 '14 at 12:46
  • I tried that. Used a 320 x 350 9-patch and set as background. The problem is, clarity it looks so dull now. But I see lot of apps having clear full screen images. – Archie.bpgc Feb 05 '14 at 13:12
  • Your problem is that the image is too big and probably you need its detail level. Is there a smart way of composing the image? Otherwise your only option is to reduce its size by losing quality ... – gunar Feb 05 '14 at 13:38
  • it would do good if you reduce the size of the image, even if you target a 10" device, it would never have screen size as the image size you have mentioned – Rat-a-tat-a-tat Ratatouille Feb 07 '14 at 12:39
  • @Rat-a-tat-a-tatRatatouille There are lots of them [Here](http://developer.android.com/guide/practices/screens_support.html#screens-table) – Archie.bpgc Feb 07 '14 at 14:44

5 Answers5

3
Picasso.with(context).load(R.drawable.bg).into(iv);

USe picaso image loader for that ots very efficent link

Digvesh Patel
  • 6,503
  • 1
  • 20
  • 34
3

Picasso and Universal-image-loader are the libraries i have used to load large images.

Picasso: http://square.github.io/picasso/

Universal-image-loader: https://github.com/nostra13/Android-Universal-Image-Loader

Also putting android:largeHeap="true" in your Manifest will grant you extra memory for heavy processes.

Luciano Rodríguez
  • 2,239
  • 3
  • 19
  • 32
0

I once had the same issue but it was an easy mistake.

If you have your background in the drawable folder, this will help you.

Because if you put your background in the drawable folder it will automatically be scaled up for your xhdpi screen, so it will try to load an image of 3200 * 3600 which will give you OutOfMemory errors. You need to put your image in either drawable-nodpi or drawable-xxhdpi. I recommend the second one because your image will be scaled down for low res screen (which also often have low memory available).

Stephane Mathis
  • 6,542
  • 6
  • 43
  • 69
0

I had this problem - I ended up lowering the quality of the image:

    public NSData fixSize(UIImage file)
    {
        if (file.Size.Width > 400 || file.Size.Height > 400)
        {
            // Figure out the ratio
            double ratioX = (double)400 / (double)file.Size.Width;
            double ratioY = (double)400 / (double)file.Size.Height;
            // use whichever multiplier is smaller
            double ratio = ratioX < ratioY ? ratioX : ratioY;

            // now we can get the new height and width
            int newHeight = Convert.ToInt32(file.Size.Height * ratio);
            int newWidth = Convert.ToInt32(file.Size.Width * ratio);
            Console.WriteLine("rescaling image to y:" + newHeight.ToString() + " and x:" + newWidth.ToString());
            file = file.Scale(new Size((int)newWidth, (int)newHeight));
        }

        if (file == null) return null;
        Console.WriteLine("setting image data to quality " + quality.ToString());
        NSData data = file.AsJPEG(quality);
        if (data.Length > 400000)
        {
            quality -= 0.1f;
            if (quality - 0.1f < 0.1f)
            {

            }
            Console.WriteLine("image data still too large will try at " + quality.ToString());
            fixSize(file);
        }
        return data;
    }

As you can see it loops over the image gradually decreasing the quality until it is a manageable size.

Arachnid
  • 280
  • 1
  • 3
  • 12
-1

There are some tutorial about

Loading Large Bitmaps

Where i found content like

To avoid java.lang.OutOfMemory exceptions, check the dimensions of a bitmap before decoding it, unless you absolutely trust the source to provide you with predictably sized image data that comfortably fits within the available memory.

Edited:

I suggest to use AQuery (android-query)

//fetch and set the image from internet, cache with file and memory 
aq.id(R.id.image1).image("http://www.vikispot.com/z/images/vikispot/android-w.png");

//returns the cached file by url, returns null if url is not cached
File file = aq.getCachedFile(url);
Community
  • 1
  • 1
Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
  • Yeah `check the dimensions of a bitmap before decoding it` The dimensions as I explained in the Question results in **inSampleSize = 1**. Meaning I have to use the whole image as it is. – Archie.bpgc Feb 05 '14 at 13:59
  • I started with the link. The above code of mine is from that link. – Archie.bpgc Feb 07 '14 at 11:08