how do you pass images (bitmaps) between android activities using bundles?

AndroidImageBundle

Android Problem Overview


Suppose I have an activity to select an image from the gallery, and retrieve it as a BitMap, just like the example: here

Now, I want to pass this BitMap to be used in an ImageView for another activity. I am aware bundles can be passed between activities, but how would I store this BitMap into the bundle?

or is there another approach I should take?

Android Solutions


Solution 1 - Android

I would highly recommend a different approach.

It's possible if you REALLY want to do it, but it costs a lot of memory and is also slow. It might not work if you have an older phone and a big bitmap. You could just pass it as an extra, for example intent.putExtra("data", bitmap). A Bitmap implements Parcelable, so you can put it in an extra. Likewise, a bundle has putParcelable.

If you want to pass it inbetween activities, I would store it in a file. That's more efficient, and less work for you. You can create private files in your data folder using MODE_PRIVATE that are not accessible to any other app.

Solution 2 - Android

If you pass it as a Parcelable, you're bound to get a JAVA BINDER FAILURE error. So, the solution is this: If the bitmap is small, like, say, a thumbnail, pass it as a byte array and build the bitmap for display in the next activity. For instance:

in your calling activity...

Intent i = new Intent(this, NextActivity.class);
Bitmap b; // your bitmap
ByteArrayOutputStream bs = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 50, bs);
i.putExtra("byteArray", bs.toByteArray());
startActivity(i);

...and in your receiving activity

if(getIntent().hasExtra("byteArray")) {
	ImageView previewThumbnail = new ImageView(this);
	Bitmap b = BitmapFactory.decodeByteArray(
		getIntent().getByteArrayExtra("byteArray"),0,getIntent().getByteArrayExtra("byteArray").length);		
    previewThumbnail.setImageBitmap(b);
}

Solution 3 - Android

As suggested by @EboMike I saved the bitmap in a file named myImage in the internal storage of my application not accessible my other apps. Here's the code of that part:

public String createImageFromBitmap(Bitmap bitmap) {
	String fileName = "myImage";//no .png or .jpg needed
	try {
		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
		bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
		FileOutputStream fo = openFileOutput(fileName, Context.MODE_PRIVATE);
		fo.write(bytes.toByteArray());
		// remember close file output
		fo.close();
	} catch (Exception e) {
		e.printStackTrace();
		fileName = null;
	}
	return fileName;
}

Then in the next activity you can decode this file myImage to a bitmap using following code:

Bitmap bitmap = BitmapFactory.decodeStream(context
					.openFileInput("myImage"));//here context can be anything like getActivity() for fragment, this or MainActivity.this

Note A lot of checking for null and scaling bitmap's is ommited.

Solution 4 - Android

Activity

To pass a bitmap between Activites

Intent intent = new Intent(this, Activity.class);
intent.putExtra("bitmap", bitmap);

And in the Activity class

Bitmap bitmap = getIntent().getParcelableExtra("bitmap");

Fragment

To pass a bitmap between Fragments

SecondFragment fragment = new SecondFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap);
fragment.setArguments(bundle);

To receive inside the SecondFragment

Bitmap bitmap = getArguments().getParcelable("bitmap");

Transferring large bitmap (Compress bitmap)

If you are getting failed binder transaction, this means you are exceeding the binder transaction buffer by transferring large element from one activity to another activity.

So in that case you have to compress the bitmap as an byte's array and then uncompress it in another activity, like this

In the FirstActivity

Intent intent = new Intent(this, SecondActivity.class);

ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPG, 100, stream);
byte[] bytes = stream.toByteArray(); 
intent.putExtra("bitmapbytes",bytes);

And in the SecondActivity

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

Solution 5 - Android

Bitmap is Parcelable so you can add using [putExtra(String,Parcelable)][2] method, But not sure it is a best practice, If it is large size data it is better to store in a single place and use from both activities.

[2]: http://developer.android.com/reference/android/content/Intent.html#putExtra(java.lang.String, android.os.Parcelable)

Solution 6 - Android

in first.java

Intent i = new Intent(this, second.class);
    				i.putExtra("uri",uri);
    				startActivity(i);

in second.java

Bundle bd = getIntent().getExtras();
		Uri uri = bd.getParcelable("uri");
		Log.e("URI", uri.toString());
		try {
			Bitmap bitmap = Media.getBitmap(this.getContentResolver(), uri);
			imageView.setImageBitmap(bitmap);

		} 
		catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

Solution 7 - Android

I had to rescale the bitmap a bit to not exceed the 1mb limit of the transaction binder. You can adapt the 400 the your screen or make it dinamic it's just meant to be an example. It works fine and the quality is nice. Its also a lot faster then saving the image and loading it after but you have the size limitation.

public void loadNextActivity(){
    Intent confirmBMP = new Intent(this,ConfirmBMPActivity.class);

    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    Bitmap bmp = returnScaledBMP();
    bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream);

    confirmBMP.putExtra("Bitmap",bmp);
    startActivity(confirmBMP);
    finish();

}
public Bitmap returnScaledBMP(){
    Bitmap bmp=null;
	bmp = tempBitmap;
	bmp = createScaledBitmapKeepingAspectRatio(bmp,400);
    return bmp;

}

After you recover the bmp in your nextActivity with the following code:

protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_confirmBMP);
	Intent intent = getIntent();
	Bitmap bitmap = (Bitmap) intent.getParcelableExtra("Bitmap");

}

I hope my answer was somehow helpfull. Greetings

Solution 8 - Android

Write this code from where you want to Intent into next activity.

    yourimageView.setDrawingCacheEnabled(true); 
    Drawable drawable = ((ImageView)view).getDrawable(); 
    Bitmap bitmap = imageView.getDrawingCache();
    Intent intent = new Intent(getBaseContext(), NextActivity.class);
    intent.putExtra("Image", imageBitmap);

In onCreate Function of NextActivity.class

Bitmap hotel_image;
Intent intent = getIntent();
hotel_image= intent.getParcelableExtra("Image");

Solution 9 - Android

You can pass image in short without using bundle like this This is the code of sender .class file

Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher;
Intent intent = new Intent();
Intent.setClass(<Sender_Activity>.this, <Receiver_Activity.class);
Intent.putExtra("Bitmap", bitmap);
startActivity(intent);

and this is receiver class file code.

Bitmap bitmap = (Bitmap)this.getIntent().getParcelableExtra("Bitmap");
ImageView viewBitmap = (ImageView)findViewById(R.id.bitmapview);
viewBitmap.setImageBitmap(bitmap);

No need to compress. that's it

Solution 10 - Android

It's better to save the file in temp/cache folder and pass the file path through intent data as I did it. here is sample code:

from on Button Click (Here bitmapFullScreen is a bitmap data which I have collected from Live Server)

Intent intent = new Intent(context, FullscreenActivity.class);
String fPath = CreateTempFile(bitmapFullScreen);
if(!StringUtils.isEmpty(fPath)) {
	intent.putExtra("image", fPath);
	startActivity(intent);
}

Function to create a File on Temp/Cache folder

public String CreateTempFile(Bitmap mBitmap) {
	File f3 = new File(Environment.getExternalStorageDirectory() + "/inpaint/");
	if (!f3.exists())
		f3.mkdirs();

	OutputStream outStream = null;
	SimpleDateFormat dateFormatter;
	dateFormatter = new SimpleDateFormat("MMddyyyyhhmmss", Locale.US);
	String FN = Environment.getExternalStorageDirectory() + "/inpaint/" + dateFormatter.format(Calendar.getInstance().getTime()) + ".png";
	File file = new File(FN);
	try {
		outStream = new FileOutputStream(file);
		mBitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
		outStream.close();
		return file.getAbsolutePath();
	} catch (Exception e) {
		e.printStackTrace();
	}
	return "";
}

2nd File where we need the file

Global var

String FileName = "";

Receive the Intent String data as FilePath to View Image on ImageView this code will be onCreate

ImageView imgUpload = findViewById(R.id.imgUpload);
try {
	if (getIntent().hasExtra("image")) {
		FileName = getIntent().getStringExtra("image");
		Bitmap b = BitmapFactory.decodeFile(FileName);
		imgUpload.setImageBitmap(b);
	}
} catch (Exception ex) {
	Toast.makeText(context, "Error: " + ex.getMessage(), Toast.LENGTH_LONG).show();
}

After display the Image we need to delete temp file

@Override
public void onBackPressed() {
	super.onBackPressed();
	try {
		File file = new File(FileName);
		file.delete();
	} catch (Exception ex) {
		Toast.makeText(context, "Error: " + ex.getMessage(), Toast.LENGTH_LONG).show();
	}
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondamonkashuView Question on Stackoverflow
Solution 1 - AndroidEboMikeView Answer on Stackoverflow
Solution 2 - AndroidHarlo HolmesView Answer on Stackoverflow
Solution 3 - AndroidIllegal ArgumentView Answer on Stackoverflow
Solution 4 - Androidcapt.swagView Answer on Stackoverflow
Solution 5 - AndroidSudar NimalanView Answer on Stackoverflow
Solution 6 - AndroidJahhView Answer on Stackoverflow
Solution 7 - AndroidJan ZiesseView Answer on Stackoverflow
Solution 8 - AndroidWajid khanView Answer on Stackoverflow
Solution 9 - AndroidAbdul QadirView Answer on Stackoverflow
Solution 10 - AndroidMonzurView Answer on Stackoverflow