How can I pass an image, drawable type between activities?
I try this:
private Drawable imagen;
Bundle bundle = new Bundle();
bundle.putSerializable("imagen", (Serializable) unaReceta.getImagen());
Intent myIntent = new Intent(v.getContext(), Receta.class);
myIntent.putExtras(bundle);
startActivityForResult(myIntent, 0);
But it reports me an execption:
java.lang.ClassCastException: android.graphics.drawable.BitmapDrawable
1) Passing in intent as extras
In the Activity A you decode your image and send it via intent:
Using this method (extras) image is passed in 162 milliseconds time interval
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] b = baos.toByteArray();
Intent intent = new Intent(this, ActivityB.class);
intent.putExtra("picture", b);
startActivity(intent);
In Activity B you receive intent with byte array (decoded picture) and apply it as source to ImageView:
Bundle extras = getIntent().getExtras();
byte[] b = extras.getByteArray("picture");
Bitmap bmp = BitmapFactory.decodeByteArray(b, 0, b.length);
ImageView image = (ImageView) findViewById(R.id.imageView1);
image.setImageBitmap(bmp);
2) Saving image file and passing its reference to another activity
WHY to do so? - taken from http://groups.google.com/group/android-developers/browse_frm/thread/9309931b3f060284#
"The size limit is: keep it as small as possible. Definitely don't put
a bitmap in there unless it is no larger than an icon (32x32 or
whatever).
In *Activity A* save the file (Internal Storage)
String fileName = "SomeName.png";
try {
FileOutputStream fileOutStream = openFileOutput(fileName, MODE_PRIVATE);
fileOutStream.write(b); //b is byte array
//(used if you have your picture downloaded
// from the *Web* or got it from the *devices camera*)
//otherwise this technique is useless
fileOutStream.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
Pass location as String to Activity B
Intent intent = new Intent(this, ActivityB.class);
intent.putExtra("picname", fileName);
In *Activity B* retrieve the file
Bundle extras = getIntent().getExtras();
String fileName = extras.getString("picname");
Make *drawable* out of the picture
File filePath = getFileStreamPath(fileName);
Drawable d = Drawable.createFromPath(filePath.toString());
Apply it to the ImageView resource
someImageView.setBackgroundDrawable(d);
You can tag each image (in the xml, or programmaticlly) with the image resource name (like "img1.png"),
then retrieve the image name using the getTag();
Then use getResources().getIdentifier(image name,"drawable", .getPackageName()) to get the drawable resource id.
And just pass the resource id through the intent -
intent.putExtra("img 1",resource id);
Lastly the result Activity can create the image from the resource using:
getResources().getDrawable(intent.getIntExtra("img 1",-1));
Drawable objects are not inherently serializable, so they cannot be passed directly in Intent extras. You must find another way to serialize or persist the image data and retrieve it in the new Activity.
For example, if you are working with BitmapDrawable instances, the underlying Bitmap could be written out to a file and read back, or serialized into a byte array (if its small enough) and the byte array could be passed via extras of an Intent.
HTH
Much much much better not to pass (or serialize) Drawables around among Activities. Very likely your are getting the drawable out of a resource. Hence there's a resource ID. Pass that around instead, that's just an int. And re-hydrate the Drawable in the other Activity.
If the Drawable is not coming from a resource, but it's built at runtime in memory ... well let's speak about it. #Devunwired has a nice suggestion in that case.
You can simply use a native buildDrawingCache method:
ImageView imageView = imageLayout.findViewById (R.id.img_thumb);
imageView.buildDrawingCache ();
Bundle extras = new Bundle ();
extras.putParcelable ("image", imageView.getDrawingCache ());
Intent intent = new Intent (this, ImageActivity.class);
intent.putExtras (extras);
startActivity (intent);
then get it at your ImageActivity:
Bundle bundle = getIntent ().getExtras ();
if (bundle != null) {
ImageView imageView = findViewById (R.id.img_full);
Bitmap image = bundle.getParcelable ("image");
imageView.setImageBitmap (image);
}
In case you pull those images from web and load them again and again, caching them would be really good option since you'll decrease network traffic and increase loading speed. I suggest using WebImageView from Droid-Fu. Really good solution, used it on some projects and I'm very satisfied with it.
I don't know if this is the case, but if the reason why you are trying to pass a drawable is because you are using an Imageview, just put the resource id in the imageview's tag, pass the tag as an Integer instead of the drawable in the intent's extra and use the following line in the receiving activity:
imageView.setImageDrawable(getResources().getDrawable(getIntent().getIntExtra("image_id",0)));
Hope it will help someone.
Related
I have wrote an app with 2 activities. One activity took a picture and the second one use it with some filters.
Activity 1:
Intent FilterSelectionIntent = new Intent(getActivity(), PulsFiltersActivity.class);
FilterSelectionIntent.putExtra("PicTaken", currentBitmap);
startActivity(FilterSelectionIntent);
Acitivity 2:
Bundle bd = intent.getExtras();
mBitmap = bd.getParcelable("PicTaken");
I have put some breakpoints in the Activity 2 and it never stop at. As soon as I comment the "putExtra" in comment, I can reach the breakpoints. In my case, the activity is not started, I think the intent is wrong.
I know that one solution is to use Bitmap.compress and forward the result in the Output stream. but in my case, it take too much time. My android device is a very basic one and it takes 2s to save the bmp. this why I try to use the intent to pass argument but it seems not working.
I'm also open to save the bmp as tmp file but I can lose 2 sec.
Any idea .
Bitmap implements Parcelable, so you could always pass it in the intent:
Intent intent = new Intent(this, NextActivity.class);
intent.putExtra("BitmapImg", bitmap);
and retrieve it on the other end:
Intent intent = getIntent();
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImg");
Check it here : How can I pass a Bitmap object from one activity to another
I think you have confused a couple of concepts of sending objects. In your Activity 1, you put the extra directly to the intent. In Activity 2, you try to get it back from a Bundle, which you did not put the Bitmap to. So try this in your activity 2:
mBitmap = (Bitmap) intent.getParcelableExtra("PicTaken");
Edit: I found some reports of Bitmaps being too big to send and activites not starting when sending Bitmaps. Converting them to ByteArray may help.
You also can store the bitmap into internal storage like this:
final static String IMG_PATH= "bmp2Store"
FileOutputStream streamOut;
Bitmap image = currentBitmap;
try {
// Store bitmap into internal storage
streamOut = mContext.openFileOutput(IMG_PATH, Context.MODE_PRIVATE);
image.compress(Bitmap.CompressFormat.PNG, 100, streamOut);
streamOut.close();
// Call ActivityB
Intent intent= new Intent(this, ConsumirOfertaActivity.class);
startActivity(intent);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
And in the activityB:
final static String IMG_PATH= "bmp2Store"
Bitmap bitmap;
FileInputStream streamIn;
try {
streamIn = openFileInput(IMG_PATH);
bitmap = BitmapFactory.decodeStream(streamIn);
streamIn.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You should not pass bitmap inside bundle:
Size of the data you are allowed to pass through Bundle or Intent is very less (~1MB). Considering a object like Bitmap, there are high chances that memory allocated to it greater than 1MB. This can happen for any kind of object including byte array, String etc.
Solution:
Store your bitmap into File, FileProvider, Singleton (as WeakReference of course) class, etc before starting Activity B, and pass just URI as parameter in Bundle.
Also check out this posts:
Intent.putExtras size limit? and
Maximum length of Intent putExtra method? (Force close)
I have an activity with an ImageView and I want to send this ImageView in an other activity, how can I do this?
You can't actually pass the ImageView itself. You can however, pass it's value and re-load that in your other Activity in it's own new ImageView.
You can pass data between Activitys in the intent.
This goes per example like this;
Intent intent = new Intent(this, MyNewActivity.class);
intent.putExtra("EXTRA_IMAGEVIEW_URL", myImageViewData);
startActivity(intent)
Then in the started (MyNewActivity) you can fetch that data again;
String imageview_url = getIntent().getStringExtra("EXTRA_IMAGEVIEW_URL");
Use whatever method is appropriate for your type of data.
edit note:
This solution is assuming that you send a simple pointer to the image, not the image itself. You either send the URL or URI from where you load it, your drawable ID or the image path in your file system. Indeed, do not try to send the whole image itself as a base64, binary or whatever you come up with.
You cannot pass imageviews between activties.
Assuming you need to pass the image from one activity to another.
You can pass bitmap by converting it to bytearray as below
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Pass byte array into intent:-
Intent intent = new Intent(FirstActivity.this, NextActivity.class);
intent.putExtra("picture", byteArray);
startActivity(intent);
In NextActivity Get Byte Array from Bundle and Convert into Bitmap Image:-
Bundle extras = getIntent().getExtras();
byte[] byteArray = extras.getByteArray("picture");
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
ImageView image = (ImageView) findViewById(R.id.imageView1);
image.setImageBitmap(bmp);
Update : 5-9-2019
Note: It is better to store the image in some place on the disk and then pass only the path to the image to next activity. The above might not work if the image is huge.
you can either subclass imageview and implement serializable interface and pass it with this way or you can pass resource id(int) of imageview to another activity then load that activity's imageview with this resource id or you make imageview static and then at the other acitvity you simply call it via FirstClass.imageView
Passing bitmap by converting it to bytearray works fine with me
This code save the image in " MyApp ".but how to load the image in other activity
final EditText txtRegid = (EditText)this.findViewById(R.id.regid);
String RegID = txtRegid.getText().toString();
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File mImageFile = new File(Environment.getExternalStorageDirectory()+File.separator+"MyApp",
"PIC"+RegID+".jpg");
String mSelectedImagePath = mImageFile.getAbsolutePath();
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mImageFile));
startActivityForResult(intent, TAKE_PICTURE);
Well, if you have defined the BitMap variable as a data member of your MyApp class, you can easily fetch it in other activities by using a getter() function to fetch that BitMap image which you are storing in MyApp.
Or, you could pass your image along with Intent, by encoding it into String format.
If you know the absolute path of the file. You can use BitmapFactory.decodeFile(filePath, opts) method to get the Bitmap. Then use ImageView's method setImageBitmap() to show it.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Passing image from one activity another activity
my app uses following logic: a button click in Activity A starts the phone camera, after a picture/video is taken (the user pressed "save" in the camera window) Activity B starts. That Activity B contains a preview of taken picture/video and the possibility to upload the media data via a http request. I'm not sure how to pass the taken Image/Video to Activity B.. I can't launch the camera with StartActivityForResult in Activity A since the result must be delivered to Activity B. Any ideas ho to do that?
There are 3 Solutions to solve this issue.
1) First Convert Image into Byte Array and then pass into Intent and in next activity get byte array from Bundle and Convert into Image(Bitmap) and set into ImageView.
Convert Bitmap to Byte Array:-
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Pass byte array into intent:-
Intent intent = new Intent(this, NextActivity.class);
intent.putExtra("picture", byteArray);
startActivity(intent);
Get Byte Array from Bundle and Convert into Bitmap Image:-
Bundle extras = getIntent().getExtras();
byte[] byteArray = extras.getByteArray("picture");
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
ImageView image = (ImageView) findViewById(R.id.imageView1);
image.setImageBitmap(bmp);
2) First Save image into SDCard and in next activity set this image into ImageView.
3) Pass Bitmap into Intent and get bitmap in next activity from bundle, but the problem is if your Bitmap/Image size is big at that time the image is not load in next activity.
One: First Save image into SDCard and in next activity set this image into ImageView.
Two: You can as well save into a byte array and pass it to next activity:
Intent A1 = new Intent(this, NextActivity.class);
A1.putExtra("pic", byteArray);
startActivity(A1);
Then in the second intent get Byte Array from Bundle and Convert into Bitmap Image.
I want to pass the Background Image that I have set to Button in PutExtra() with intent object into another Class.
Can anybody know how to do that ?
Thanks
davidbrown
Sender Activity:
Bitmap bitmap = BitmapFactory.decodeResource
(getResources(), R.drawable.sticky_notes); // your bitmap
ByteArrayOutputStream bs = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bs);
intent.putExtra("byteArray", bs.toByteArray());
Reciever Activity:
if(getIntent().hasExtra("byteArray")) {
ImageView imv= new ImageView(this);
Bitmap bitmap = BitmapFactory.decodeByteArray(
getIntent().getByteArrayExtra("byteArray"), 0, getIntent().getByteArrayExtra("byteArray").length);
imv.setImageBitmap(bitmap);
}
Intent can keep only 40 kbytes. If you can zip your images less then 40 kbytes - you can put it into extras
intent.putExtra("imageData", bitmap)
better approach is to create a link instead of passing directly bitmap.
intent.putExtra("image_url",R.drawable.image);
try this...
first get image in bitmap.
Bitmap tileImage = BitmapFactory.decodeResource(getResources(), R.drawable.floore);
Conver it in byte array.
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Bundle b = new Bundle();
b.putByteArray("camara",byteArray);
Intent intent3 = new Intent(this,Second.class);
intent3.putExtras(b);
startActivity(intent3);
You can pass Bitmap (since it's implementing Parcelable) if you're sure that it won't be deleted from memory (in other words - don't store Bitmaps like that).
Bitmap itself is just a small Java wrapper of native resources, so it won't take a lot of space.
Be careful when passing files that can be very large, such as a photo or gallery file. Even if you compress it, the size may exceed putExtra's acceptable limit. I suggest sending the image link or file path for a file from the gallery. In my app I always compress my files as max as I can, but there was always one that crashs the app.
Intent intent = new Intent(getActivity(), PhotoViewActivity.class);
intent.putExtra("url", url);
//OR file path
intent.putExtra("path", path);
startActivityForResult(intent,PHOTO_VIEW_REQUEST);
In that case on PhotoViewActivity
String url = getIntent().getStringExtra("url");
String path = getIntent().getStringExtra("path");
if(url != null && !url.isEmpty()){
//Get using Picasso or other framework
}else if(path != null && !path.isEmpty()){
//In my case I transform in Bitmap
//see this link for more detail : https://stackoverflow.com/questions/16804404/create-a-bitmap-drawable-from-file-path
}else{
//Throw exception and close activity
}
How transform path in Bitmap:
Create a Bitmap/Drawable from file path