OutOfMemoryError in BitmapFactory.decodeFile() - android

When I pick image from gallery if image size bigger than 3 Mb android the OutOfMemoryError.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, options);
This text from logs. Please help me, becouse "deadline")
E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:378)
at com.DriverNotes.AndroidMobileClientTest.ProfileActivity.onActivityResult(ProfileActivity.java:104)
at android.app.Activity.dispatchActivityResult(Activity.java:5456)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3402)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3449)
at android.app.ActivityThread.access$1200(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1328)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)

OutofMemory occurs when your app exceeds memory allocated in heap. The bitmap is too large to fit in memory ie heap. In such a case you run out of memory. You need to scale down the bitmap and then use the same.
For that check this link
try this code may help you,
public static Bitmap decodeFile(File f,int WIDTH,int HIGHT){
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_WIDTH=WIDTH;
final int REQUIRED_HIGHT=HIGHT;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_WIDTH && o.outHeight/scale/2>=REQUIRED_HIGHT)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap bm = BitmapFactory.decodeFile(path,options);

Try this.
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inDither=false; //Disable Dithering mode
bmOptions.inPurgeable=true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bmOptions.inInputShareable=true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
bmOptions.inTempStorage=new byte[32 * 1024];
Bitmap mainBitmap = BitmapFactory.decodeFile(filePath, bmOptions);

Related

Bitmap size much greater than file size from which it's loaded

I'm using the following code to retrieve an bitmap from image file in android:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
However, the size of the bitmap is more than double the size of file. Eg, for a file of size 520kb, the bitmap size is around 1.3MB. Is there a way I can get the bitmap of the same size as that of file?
The bitmap size is pure memory data without compression. You can calculate the size with 4 bytes per pixel (with your settings).
Your file is probably in a compressed format like jpg. Without a compression it would take up the same space.
The reason why the bitmap is kept uncompressed in memory is basically the performance. You can read the data and work with it much faster in an uncompressed way. For example if you would like to see what color a specific pixel has, you would need to uncompress the data first. That takes time and the more pixels you check the more time it would take.
While reading the file from the storage, the uncompression just takes an ignorable amount of time compared to the complete reading process. So you will not have a big performance impact compared to "on demand" uncompression.
try like this may help you,
public static Bitmap decodeFile(File f,int WIDTH,int HIGHT){
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_WIDTH=WIDTH;
final int REQUIRED_HIGHT=HIGHT;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_WIDTH && o.outHeight/scale/2>=REQUIRED_HIGHT)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}

android-getting error out of memory with showing images

I've an imageview that shows an image everytime user run the app . the images are in drawable folder .
every so often the app crash and in the lof cat it says java.lang.outOfMemmoryError
I've lots of images, about 100 images. 100,000 Byet .
What is the solution to show these images to don't use lot of memory ?
thanks so much
To fix OutOfMemory you should do something like that:
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap=BitmapFactory.decodeStream(is,null,options);
This inSampleSize option reduces memory consumption.
Here's a complete method. First it reads image size without decoding the content itself. Then it finds the best inSampleSize value, it should be a power of 2. And finally the image is decoded.
private Bitmap decodeFile(File f){
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_SIZE=70;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}

Loading Multiple Image From server in android Give VM Buget out of memory?

I am using lazy loader example but my application give following error in Logcat.
12-14 15:27:55.987: E/dalvikvm-heap(27566): 2457600-byte external allocation too large for this process.
12-14 15:27:55.992: E/(27566): VM won't let us allocate 2457600 bytes
12-14 15:27:55.992: D/skia(27566): --- decoder->decode returned false
I am use Imageloader class in that write
private Bitmap decodeFile(File f){
try {
//decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
o.inPurgeable = true; // Tell to garbage collector that whether it needs free memory, the Bitmap can be cleared
o.inTempStorage = new byte[32 * 1024];
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE=70;
int width_tmp=o.outWidth, height_tmp=o.outHeight;
int scale=1;
while(true){
if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
break;
width_tmp/=2;
height_tmp/=2;
scale*=2;
}
//decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inPurgeable = true; // Tell to garbage collector that whether it needs free memory, the Bitmap can be cleared
o2.inTempStorage = new byte[32 * 1024];
o2.inSampleSize=scale;
Bitmap bitmap1=BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
// System.out.println("width : "+bitmap1.getWidth()+ " height : "+bitmap1.getHeight());
/* if(bitmap1.getHeight()>=bitmap1.getWidth())
{
bitmap1 = Bitmap.createScaledBitmap(bitmap1, bitmap1.getHeight(),bitmap1.getWidth(), true);
}else{
//bmp = Bitmap.createScaledBitmap(bmp, (int) height2,width, true);
Matrix matrix = new Matrix();
matrix.postRotate(270);
bitmap1 = Bitmap.createBitmap(bitmap1 , 0, 0, bitmap1 .getWidth(), bitmap1 .getHeight(), matrix, true);
}*/
return bitmap1;
} catch (FileNotFoundException e) {}
return null;
}
but i use sacle =scale*1 because i want HD image in that use scale-scale*2 then my image like blur..
then what i do?
I recommend you use the library Picasso It is simpler than Android-Universal-Image-Loader but just as powerful.
you dont need to do all this . try this library . this is awesome .
Android-Universal-Image-Loader

Album artwork from mp3

i managed to read album artwork from my mp3 file(on sdcard) but the picture is
biger than activity. How can i downsize(compress) picture to 150x150 pixels?
You can use "fitXY" to scale an ImageView:
<ImageView android:layout_width="150dp"
android:layout_height="150dp"
android:scaleType="fitXY" />
You can set the source of the ImageView programmatically.
The following piece of code will do the trick ;)
public static Bitmap decodeFile(File f, boolean goodQuality){
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_SIZE=100;
//Find the correct scale value. It should be the power of 2.
int scale=1;
if(!goodQuality){
while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
scale*=2;
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}

Android Bitmap bigger than heapSize

I'm getting the error: java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=12295KB, Allocated=3007KB, Bitmap Size=15621KB)
The bitmap size is larger than my heapSize.. So how can I make the bitmap smaller? Here is the code where it crashes:
private Bitmap getPicture(int position) {
Bitmap bmpOriginal = BitmapFactory.decodeFile(mFileLocations.get(position));
Bitmap bmResult = Bitmap.createBitmap(bmpOriginal.getWidth(), bmpOriginal.getHeight(), Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(bmResult);
tempCanvas.rotate(90, bmpOriginal.getWidth()/2, bmpOriginal.getHeight()/2);
tempCanvas.drawBitmap(bmpOriginal, 0, 0, null);
bmpOriginal.recycle();
}
it crashes at line:
Bitmap bmResult = Bitmap.createBitmap(bmpOriginal.getWidth(), bmpOriginal.getHeight(), Bitmap.Config.RGB_565);
and my decodeFile:
private Bitmap decodeFile(String f){
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
//The new size we want to scale to
final int REQUIRED_SIZE=70;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
Log.d(LOG_TAG, "Failed to decode file");
}
return null;
}
Scale down your image to be in VM Budget...
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile( filename, options );
options.inJustDecodeBounds = false;
options.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile( filename, options );
if ( bitmap != null ) {
bitmap = Bitmap.createScaledBitmap( bitmap, width, height, false );
}
Change sample size to whatever you want like 2, 4, 6, 8 etc..
For full details refer to this from Android developers site which was posted rescently, it clearly states what you need to do to be in VM budget..
Two things:
It appears that you are using the BitmapFactory.decodeFile method instead of the method you have posted.
Also it looks like the only information you are keeping from bmpOriginal are its dimensions. So why not just use BitmapFactory.inJustDecodeBounds like you do in your decodeFile method. Or do just recycle the bitmap before you create the new one while retaining its dimensions, like this:
int width = bmpOriginal.getWidth();
int height = bmpOriginal.getHeight();
bmpOriginal.recycle();
Bitmap bmResult = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
This was recently covered in AndroidDevelopers+ :
https://plus.google.com/103125970510649691204/posts/1oSFSyv3pRj

Categories

Resources