0

I'm new to android and developing an app that saves large images from drawable folder to phone storage. These files have resolution of 2560x2560 and I want to save these files without loosing image quality.

I use following method to save images and it gives me Out of Memory Exception. I have seen many answers how to load a large bitmap efficiently. But I cant really find an answer for this problem.

In my code, I use

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imageId);
File file = new File(root.getAbsolutePath() + "/Pictures/" + getResources().getString(R.string.app_name) + "/" + timeStamp + ".jpg");
file.createNewFile();
FileOutputStream oStream = new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 100, oStream);
oStream.close();
bitmap.recycle();

Is there anything wrong with my code? This works without any exception for smaller images.

If I use android:largeHeap="true", this does not throw any exception. But I know it is not a good practice to use android:largeHeap="true".

Is there any efficient way to save large images from drawable folder without an exception?

Thank you in advance.

1 Answer 1

3

If you just want to copy the image file, you shouldn't decode it into a bitmap in the first place.

You can copy a raw resource file with this for example:

InputStream in = getResources().openRawResource(imageId);
String path = root.getAbsolutePath() + "/Pictures/" + getResources().getString(R.string.app_name) + "/" + timeStamp + ".jpg";
FileOutputStream out = new FileOutputStream(path);
try {
    byte[] b = new byte[4096];
    int len = 0;
    while ((len = in.read(b)) > 0) {
        out.write(b, 0, len);
    }
}
finally {
    in.close();
    out.close();
}

Note that you have to store your image in the res/raw/ directory instead of res/drawable/.

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

4 Comments

Agreed. Or, store them as assets (e.g., in src/main/assets/ of an Android Studio module), and copy them from there (call open() on the AssetManager that you get by calling getAssets()).
@Floern It looks like a good idea. But I load same images to my app's ImageView (using external lib called Subsampling Scale Image View by davemorrissey). So if I put those images in raw folder, the app simply crash with Out of Memory exception again (at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:500)).
@VajiraLasantha it crash because your device does not have enough RAM to hold your image. Your ImageView should be smaller than your screen, so you can resize your image to fit your ImageView then display it. Here is useful link: developer.android.com/training/displaying-bitmaps/…
@Floern Fixed it. Used Bitmap.Config.RGB_565 and inDither = true options when decoding bitmap from raw image file to display in ImageView and it works fine now. Thank you for your answer.

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.