82

I hava a Bitmap variable named bmp in Activity1 , and I want to send the bitmap to Activity2

Following is the code I use to pass it with the intent.

Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",bmp);
startActivity(in1);

And in Activity2 I try to access the bitmap using the following code

Bundle ex = getIntent().getExtras();
Bitmap bmp2 = ex.getParceable("image");
ImageView result = (ImageView)findViewById(R.Id.imageView1);
result.setImageBitmap(bmp);

The application runs without an exception but it does not give the expected result

Ismail Iqbal
  • 2,774
  • 1
  • 25
  • 46
adi.zean
  • 1,085
  • 3
  • 12
  • 15
  • 3
    This is not a copy of your code, as I see at least two typo's. – Christine Jun 13 '12 at 07:57
  • @Christine : this is realy my code hehe,,, but i had it from many tutorial... XP – adi.zean Jun 13 '12 at 08:29
  • 2
    So how come you create a Bitmap bmp2, and you set it with setImageBitmap(bmp)? And surely, R.Id.imageView1 does not work. It should be R.id.imageView1. – Christine Jun 13 '12 at 21:01
  • 3
    You could of course write the bitmap to a file, and read this file in the second activity. You can use the same file to make sure the image remains if the device is rotated. – Christine Jun 13 '12 at 21:03
  • 1
    Before posting a question, make sure you understand the code you are posting, a plain copy-paste from StackOverflow to fix a bug is useless.. @Christine - I was about to comment the same thing about typos.. – milosmns May 09 '15 at 08:59
  • Possible duplicate of [How can I pass a Bitmap object from one activity to another](https://stackoverflow.com/questions/2459524/how-can-i-pass-a-bitmap-object-from-one-activity-to-another) – AdamHurwitz Jun 17 '19 at 05:14

8 Answers8

230

Convert it to a Byte array before you add it to the intent, send it out, and decode.

//Convert to byte array
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();

Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",byteArray);

Then in Activity 2:

byte[] byteArray = getIntent().getByteArrayExtra("image");
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);

edit

Thought I should update this with best practice:

In your first activity, you should save the Bitmap to disk then load it up in the next activity. Make sure to recycle your bitmap in the first activity to prime it for garbage collection:

Activity 1:

try {
    //Write file
    String filename = "bitmap.png";
    FileOutputStream stream = this.openFileOutput(filename, Context.MODE_PRIVATE);
    bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
    
    //Cleanup
    stream.close();
    bmp.recycle();

    //Pop intent
    Intent in1 = new Intent(this, Activity2.class);
    in1.putExtra("image", filename);
    startActivity(in1);
} catch (Exception e) {
    e.printStackTrace();
}

In Activity 2, load up the bitmap:

Bitmap bmp = null;
String filename = getIntent().getStringExtra("image");
try {
    FileInputStream is = this.openFileInput(filename);
    bmp = BitmapFactory.decodeStream(is);
    is.close();
} catch (Exception e) {
    e.printStackTrace();
}
starball
  • 20,030
  • 7
  • 43
  • 238
Zaid Daghestani
  • 8,555
  • 3
  • 34
  • 44
13

Sometimes, the bitmap might be too large for encode&decode or pass as a byte array in the intent. This can cause either OOM or a bad UI experience.

I suggest to consider putting the bitmap into a static variable of the new activity (the one that uses it) which will carefully be null when you no longer need it (meaning in onDestroy but only if "isChangingConfigurations" returns false).

android developer
  • 114,585
  • 152
  • 739
  • 1,270
4

Simply we can pass only Uri of the Bitmap instead of passing Bitmap object. If Bitmap object is Big, that will cause memory issue.

FirstActivity.

intent.putExtra("uri", Uri);

From SecondActivity we get back bitmap.

Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),Uri.parse(uri));
Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
2

Kotlin Code for send Bitmap to another activity by intent:

1- in First Activity :

          val i = Intent(this@Act1, Act2::class.java)
           var bStream  =  ByteArrayOutputStream()
            bitmap.compress(Bitmap.CompressFormat.PNG, 50, bStream)
            val byteArray = bStream.toByteArray()
            i.putExtra("image", byteArray )
            startActivity(i)

2- In Activity two (Read the bitmap image) :

 var bitmap : Bitmap? =null
    if (intent.hasExtra("image")){
      //convert to bitmap          
        val byteArray = intent.getByteArrayExtra("image")
        bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
    }

3- if you need to set it as background for a view, like ConstraintLayout or... :

 if (bitmap != null) {
     //Convert bitmap to BitmapDrawable
     var bitmapDrawable = BitmapDrawable( resources , bitmap)
      root_constraintLayout.backgroundDrawable = bitmapDrawable
   }
Hamed Jaliliani
  • 2,789
  • 24
  • 31
1

create a singleton class for storing bitmap data

public final class BitmapData {
    private static final BitmapData bitmapData = new BitmapData();
    private Bitmap bitmap;

    private BitmapData() {
    }

    public static BitmapData getInstance() {
        return bitmapData;
    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }

in first activity you can set like this.

BitmapData.getInstance().setBitmap(bitmap);

and in second activity

Bitmap bitmap = BitmapData.getInstance().getBitmap();

Note: check null value

Ritunjay kumar
  • 261
  • 3
  • 6
  • class BitmapData private constructor() { var bitmap: Bitmap? = null companion object { val instance = BitmapData() } } Kotlin version of above code. Thanks for this. – tbfp Jan 06 '23 at 10:54
0

We can also solve this without passing data through intent. Just store the image in the memory and in the next Activity just load the image from that location, which can also avoid app crash from passing large bitmap data. Note: You need not even pass the location path to the intent, remember the path and use it.

murali kurapati
  • 1,510
  • 18
  • 23
0

I would like to also post a best practices answer for those looking to do this (but may be asking the wrong question).

Instead of passing a bitmap around (which I presume you downloaded from the network, otherwise, you would already have a file reference to it), I recommend using an image loader such as Universal Image Loader to download an image into an ImageView. You can configure it to then cache the image to disk:

 DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .considerExifParams(true)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .build();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
                .defaultDisplayImageOptions(defaultOptions)
                .build();

        ImageLoader.getInstance().init(config);

Now, just pass the image URL in your intent and use the UIL to load the image. In your newly created activity for example, the image will load instantly because it is loading from the cache - even if your image URL has expired since the download.

Micro
  • 10,303
  • 14
  • 82
  • 120
-7
Bundle b = new Bundle();
b.putSerializable("Image", Bitmap);
mIntent.putExtras(b);
startActivity(mIntent);
Prashant Mishra
  • 627
  • 5
  • 18