1

Im trying to scale a bitmap to make it fit because some device wont show images > 2048.

I found a solution but the app crashes when I choose/take a pic.

That piece of code: (Inside onActivityResult)

currImageURI = data.getData();
                path=(getRealPathFromURI(currImageURI));

                Drawable d = Drawable.createFromPath(path);
                image.setVisibility(View.VISIBLE);
                mPhoto=drawableToBitmap(d);
                Bitmap sized = mPhoto;
                if(mPhoto.getHeight()>=2048||mPhoto.getWidth()>=2048){
                sized = Bitmap.createScaledBitmap(mPhoto, (int)(mPhoto.getWidth()*0.8), (int)(mPhoto.getHeight()*0.8), false);
                }

                image.setImageBitmap(sized);

LogCat:

08-28 22:48:14.873: E/AndroidRuntime(12047): FATAL EXCEPTION: main
08-28 22:48:14.873: E/AndroidRuntime(12047): java.lang.OutOfMemoryError
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.graphics.Bitmap.nativeCreate(Native Method)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.graphics.Bitmap.createBitmap(Bitmap.java:586)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:466)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at com.example.free.Add.onActivityResult(Add.java:149)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.app.Activity.dispatchActivityResult(Activity.java:5231)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3172)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3219)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.app.ActivityThread.access$1200(ActivityThread.java:134)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.os.Looper.loop(Looper.java:137)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at android.app.ActivityThread.main(ActivityThread.java:4856)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at java.lang.reflect.Method.invokeNative(Native Method)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at java.lang.reflect.Method.invoke(Method.java:511)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
08-28 22:48:14.873: E/AndroidRuntime(12047):    at dalvik.system.NativeStart.main(Native Method)

Line 149 is:

sized = Bitmap.createScaledBitmap(mPhoto, (int)(mPhoto.getWidth()*0.8), (int)(mPhoto.getHeight()*0.8), false);

Could you tell me what can I do to prevent it from crashing? Thanks!

Update:

App still crashes:

08-28 23:24:20.219: W/dalvikvm(16289): threadid=1: thread exiting with uncaught exception (group=0x412552a0)   
08-28 23:18:59.917: E/AndroidRuntime(15286): FATAL EXCEPTION: main
    08-28 23:18:59.917: E/AndroidRuntime(15286): java.lang.OutOfMemoryError
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.graphics.Bitmap.nativeCreate(Native Method)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.graphics.Bitmap.createBitmap(Bitmap.java:586)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at com.example.free.Add.getResizedBitmap(Add.java:335)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at com.example.free.Add.onActivityResult(Add.java:150)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.app.Activity.dispatchActivityResult(Activity.java:5231)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3172)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3219)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.app.ActivityThread.access$1200(ActivityThread.java:134)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.os.Handler.dispatchMessage(Handler.java:99)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.os.Looper.loop(Looper.java:137)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at android.app.ActivityThread.main(ActivityThread.java:4856)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at java.lang.reflect.Method.invokeNative(Native Method)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at java.lang.reflect.Method.invoke(Method.java:511)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
    08-28 23:18:59.917: E/AndroidRuntime(15286):    at dalvik.system.NativeStart.main(Native Method)

code:

currImageURI = data.getData();
                path=(getRealPathFromURI(currImageURI));

                Drawable d = Drawable.createFromPath(path);
                image.setVisibility(View.VISIBLE);
                mPhoto=drawableToBitmap(d);
                Bitmap sized = mPhoto;
                if(mPhoto.getHeight()>=2048||mPhoto.getWidth()>=2048){
                    sized=getResizedBitmap(mPhoto,(int)(mPhoto.getHeight()*0.8),(int)(mPhoto.getWidth()*0.8));
                }

                image.setImageBitmap(sized);         
mn6vdv23g
  • 734
  • 2
  • 10
  • 33

1 Answers1

1

Please have a look at my related question:

High resolution Image - OutOfMemoryError

I recommend that you put your Image into the Drawables folder. From there, load it with the appropriate size using the code below. This will reduce the memory usage of your app and will always only use as much memory as needed.

Make sure you have only one instance of your Bitmap in memory. After displaying it, call recycle() and set your reference to null.

This is how you could load your images:

public  Bitmap scaleDownBitmap(Bitmap photo, int newHeight) {

     final float densityMultiplier = getResources().getDisplayMetrics().density;

     int h= (int) (newHeight*densityMultiplier);
     int w= (int) (h * photo.getWidth()/((double) photo.getHeight()));

     photo = Bitmap.createScaledBitmap(photo, w, h, true);

     return photo;
}

Use it like this:

ImageView.setImageBitmap(scaleDownBitmap(youroldbitmap, 300));

Be aware not to use a too high value for your newHeight and keep in mind the densityMultiplier.

Taken from: Failed binder transaction when putting an bitmap dynamically in a widget

Community
  • 1
  • 1
Philipp Jahoda
  • 50,880
  • 24
  • 180
  • 187
  • How can I put the image in my drawables folder? Cant find it.. The image comes from an image chooser or the camera. Can I even do that? – mn6vdv23g Aug 28 '13 at 20:07
  • Have you tried casting your mPhoto.getWidth() and height to (float)? Like that: getResizedBitmap(mPhoto,(int)((float) mPhoto.getHeight()*0.8f),(int)((float) mPhoto.getWidth()*0.8f)); – Philipp Jahoda Aug 28 '13 at 20:30
  • sure you can, take a close look at my comment – Philipp Jahoda Aug 28 '13 at 20:33
  • But the method does it itself.. doesn't it? `float scaleWidth = ((float) newWidth) / width;` – mn6vdv23g Aug 28 '13 at 20:35
  • Yes, but if mPhoto.getHeight() returns an Integer value, this calculation will be useless: (int)(mPhoto.getHeight()*0.8), it will always result in mPhoto.getHeight() since 0.8 turns to 1. – Philipp Jahoda Aug 28 '13 at 20:37
  • I understand. But what can I do about it? I can change the variables that `getResizedBitmap` gets.. Sorry for not understanding you lol. Is that what I should do? – mn6vdv23g Aug 28 '13 at 20:41
  • See my updated answer, that is what you should do :) Im not sure if that will work, its just an idea that came to my mind. – Philipp Jahoda Aug 28 '13 at 20:42
  • It looks weird, but Im trying it now. – mn6vdv23g Aug 28 '13 at 20:46
  • Also im not sure if the factor 0.8 is enough. What if an image with sizes of 5000 x 3000 is resized. It would still be 4000x2400 after resizing. – Philipp Jahoda Aug 28 '13 at 20:47
  • It makes a toast "width and height must be >0". Where did that toast come from?! its not even in my code.. – mn6vdv23g Aug 28 '13 at 20:48
  • You could also make a logcat output and see what the sizes of your photo are at runtime. (I am talking about the calculated sizes, not the original ones) – Philipp Jahoda Aug 28 '13 at 20:49
  • Im sure that the sizes are 100% Ok. the error is within the code. – mn6vdv23g Aug 28 '13 at 20:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/36420/discussion-between-philipp-jahoda-and-nirpes) – Philipp Jahoda Aug 28 '13 at 20:53