20

I am trying to pass Bitmap to another Activity, and I am displaying the same image from the other Activity using ImageView . And this is how I pass the Bitmap.

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK && requestCode == CAMERA_RESULT) {

        File out = new File(getFilesDir(), "newImage.jpg");

        if(!out.exists()) {

            Toast.makeText(getBaseContext(),

                    "Error while capturing image", Toast.LENGTH_LONG)

                    .show();

            return;

        }

        Bitmap mBitmap = BitmapFactory.decodeFile(out.getAbsolutePath());

        Intent bitIntent = new Intent(this, CameraTake.class);
        bitIntent.putExtra("BitmapImage", mBitmap);
        startActivity(bitIntent);

And this is how I receive the value :

 Intent intent = getIntent();
    bitmap= (Bitmap)intent.getParcelableExtra("BitmapImage");
    ImageView im1 = (ImageView)findViewById(R.id.camOut);
    im1.setImageBitmap(bitmap);

And while running the App, here is the logcat I obtain :

> 10-17 08:32:11.241  16762-16762/obx.com.futurister E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: obx.com.futurister, PID: 16762
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent {  }} to activity {obx.com.futurister/obx.com.futurister.OptionChooser}: java.lang.RuntimeException: Failure from system
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
            at android.app.ActivityThread.-wrap16(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.RuntimeException: Failure from system
            at android.app.Instrumentation.execStartActivity(Instrumentation.java:1514)
            at android.app.Activity.startActivityForResult(Activity.java:3917)
            at android.app.Activity.startActivityForResult(Activity.java:3877)
            at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:820)
            at android.app.Activity.startActivity(Activity.java:4200)
            at android.app.Activity.startActivity(Activity.java:4168)
            at obx.com.futurister.OptionChooser.onActivityResult(OptionChooser.java:75)
            at android.app.Activity.dispatchActivityResult(Activity.java:6428)
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
            at android.app.ActivityThread.-wrap16(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: android.os.TransactionTooLargeException: data parcel size 4915644 bytes
            at android.os.BinderProxy.transactNative(Native Method)
            at android.os.BinderProxy.transact(Binder.java:503)
            at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2657)
            at android.app.Instrumentation.execStartActivity(Instrumentation.java:1507)
            at android.app.Activity.startActivityForResult(Activity.java:3917)
            at android.app.Activity.startActivityForResult(Activity.java:3877)
            at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:820)
            at android.app.Activity.startActivity(Activity.java:4200)
            at android.app.Activity.startActivity(Activity.java:4168)
            at obx.com.futurister.OptionChooser.onActivityResult(OptionChooser.java:75)
            at android.app.Activity.dispatchActivityResult(Activity.java:6428)
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742)
            at android.app.ActivityThread.-wrap16(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

In a similar question , the solution recommends to use image loading libraries, should I go for that, or can this be fixed easily? Looking for professional answers. Thanks

Community
  • 1
  • 1
OBX
  • 6,044
  • 7
  • 33
  • 77
  • I think you should pass image's path, should not pass image! – Neo Oct 17 '15 at 03:21
  • I am using this : http://dharmendra4android.blogspot.in/2012/04/save-captured-image-to-applications.html to capture an Image, Can you help me identify the path from this :/ – OBX Oct 17 '15 at 03:24
  • Did you get the image in your local storage? Using `bitIntent.putExtra("BitmapImage", out.getAbsolutePath());` instead of `bitIntent.putExtra("BitmapImage", mBitmap);`. and in new Activity, you will get and load the image from the path! – Neo Oct 17 '15 at 03:29
  • Can you explain that as an Answer :) ? – OBX Oct 17 '15 at 03:29
  • 2
    `Caused by: android.os.TransactionTooLargeException: data parcel size 4915644 bytes` your bitmap is too large to fit in a transaction. put it in a file and pass the path – njzk2 Oct 17 '15 at 03:35

3 Answers3

23

The root cause has been provided in the log:

Caused by: android.os.TransactionTooLargeException: data parcel size 4915644 bytes

The maximum cap for data transport by Intent is 1 MB, so there are a few ways to pass a bitmap:

  1. Reduce bitmap size,this may or may not be a valid solution depending on your use case.
  2. Chop up the bitmap for transportation and reassembles it on the receiving end, you'll probably need to write a service for it, and it's not terribly efficient. Did it once, not recommended.
  3. Only passing the URI for the bitmap, and load it anew on the receiving Activity. This is how Intent asking Android camera app to take a picture works - the picture is saved to storage and only the URI of the stored file is returned.
  4. If the 1st and 2nd Activities are in the same process, you can skip all of above and save the bitmap to a shared cache, where there are many, many libraries to accomplish that.
Kai
  • 15,284
  • 6
  • 51
  • 82
  • Thanks for finding the cause of error :) . Now the question is , Can I fix this by passing the URI to the other Activity? – OBX Oct 17 '15 at 03:34
  • @oblivion it'll work as long as both Activities are synced in how the bitmap is passed around – Kai Oct 17 '15 at 03:35
  • 1
    Thanks, Learned today when **not** to pass using Intent :) – OBX Oct 17 '15 at 03:38
  • For me it was happening as the data I was sending via bundle to Next fragment was [>500 Kb](http://stackoverflow.com/a/8552602/1149398). I realised this might have initiated this issue to appear at random for me. – sud007 Sep 07 '16 at 13:17
  • You can also create a getter in the first class and have the 2nd class access it that way. This is what we are going to do when we migrate to android 7. – John Lord Jan 14 '19 at 02:07
8

If you could capture image and save to local storage by :

File out = new File(getFilesDir(), "newImage.jpg");

you should pass the path of out to other Activity by:

bitIntent.putExtra("BitmapImage", out.getAbsolutePath());

instead of bitIntent.putExtra("BitmapImage", mBitmap);

And in secondActivity:

Intent intent = getIntent();
String imagePath = intent.getStringExtra("BitmapImage");
File imgFile = new  File(imagePath);

if(imgFile.exists()){

    Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());

    ImageView myImage = (ImageView) findViewById(R.id.camOut);

    myImage.setImageBitmap(myBitmap);
}
Neo
  • 1,469
  • 3
  • 23
  • 40
1

We can't pass a Bitmap around through intent extras. The reason is the Inner Process Communication (IPC) bus has a 1mb limit. This limit applies to the Bundle that represents the Intent's extras

JBirdVegas
  • 10,855
  • 2
  • 44
  • 50