pass a bitmap image from one activity to another

2019-01-14 14:34发布

问题:

In my app i am displaying no.of images from gallery from where as soon as I select one image , the image should be sent to the new activity where the selected image will be set as background.However, I am able to get the images from gallery but as soon as I select one the application crashes.Thanks in advance

Activity-1(The images are shown in gallery and the selected image is sent to new activity)

public class Gallery extends Activity {

private static int RESULT_LOAD_IMAGE = 1;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gallery);

        Button buttonLoadImage = (Button) findViewById(R.id.buttonLoadPicture);


        buttonLoadImage.setOnClickListener(new View.OnClickListener() {

            public void onClick(View arg0) {

                Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

                startActivityForResult(i, RESULT_LOAD_IMAGE);
            }
        });
    }



    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {






            Uri contentUri = data.getData();          
            String[] proj = { MediaStore.Images.Media.DATA };         
            Cursor cursor = managedQuery(contentUri, proj, null, null, null);         
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);         
            cursor.moveToFirst();         
            String tmppath = cursor.getString(column_index);           
            Bitmap croppedImage = BitmapFactory.decodeFile(tmppath);


            // Bitmap croppedImage = BitmapFactory.decodeFile(croppedImage);
            Intent intent = new Intent(Gallery.this,GesturesActivity.class);
            intent.putExtra("bmp",croppedImage);
            startActivity(intent);

            Log.v("sending image","sending image");


        }


    }
}

Activity-1(XML)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/background"
    >
    <ImageView
            android:id="@+id/imgView"
            android:layout_width="fill_parent"
            android:layout_weight="1" android:layout_height="wrap_content"></ImageView>
    <Button 
            android:layout_height="wrap_content" 
            android:text="Load Picture" 
            android:layout_width="wrap_content" 
            android:id="@+id/buttonLoadPicture" 
            android:layout_weight="0" 
            android:layout_gravity="center"></Button>
</LinearLayout>

Activity-2(The activity where the selected image should be set as background image of the screen)

  public class GesturesActivity extends Activity {


        private final int MENU_CAMERA = Menu.FIRST;


        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);


            Bitmap bmp = (Bitmap)this.getIntent().getParcelableExtra("bmp");
            BitmapDrawable background = new BitmapDrawable(bmp);
            getWindow().setBackgroundDrawable(background);  //background image of the screen



            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.advert);
            View view = new SandboxView(this, bitmap);

            setContentView(view);
        }



        public boolean onPrepareOptionsMenu(Menu menu) {
            menu.clear();

                menu.add(0, 11, 0, "Take Snapshot");

                    return super.onPrepareOptionsMenu(menu);
        }


        public boolean onOptionsItemSelected(MenuItem item) {

            return super.onOptionsItemSelected(item);
        }



    }

回答1:

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.



回答2:

Since you are retrieving the image from the Gallery, why not pass the id to the next activity and retrieve the image in that activity rather than passing the image? This will help you on memory and performance.



回答3:

Bitmap implements Parcelable, so you could always pass it in the intent. try below code:

First Activity.

Intent mIntent = new Intent(this, ActivityTwo.class);
mIntent.putExtra("bmp_img", bmp);

for getting output in target activity, try:

Second Activity.

Bitmap mBitmap = (Bitmap) intent.getParcelableExtra("bmp_img");

you always use getParcelableExtra("key") for get the passing Bitmap in Activity.



回答4:

I think you can do by define your Bitmap as static and by calling classname.bitmap you can get the bitmap..and set as background in next Activity



回答5:

IGP summed it up clearly, but in my opinion the most efficient way to do it is by passing the URI of the image to the next activity, instead of the Bitmap itself. I'm actually not sure if it's possible to pass whole Bitmaps (or, converted, ByteArrays) of data from one activity to another using Intents - I believe there is a limit as to how much data a Bundle can contain.

Instead pass the reference you're using to display the image in the first activity. I assume you're using some kind of lazy loading? If not, I highly suggest you do. This way you can simply re-query for the Bitmap via the URI.

However, I am able to get the images from gallery but as soon as I select one the application crashes

I'm still puzzled as to how these kinds of problems reach SO. Check the logs, maybe you can figure it out on your own.



回答6:

Using this you can pass bitmap to another activity.

If you are using drawable than convert that drawable to bitmap first.

Bitmap bitmap = ((BitmapDrawable)d).getBitmap();

For passing that bitmap to another activity using intent use this below code snippet.

intent.putExtra("Bitmap", bitmap);

And for fetch that bitmap intent in another activity use this

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

Follow this Link for More Detail.



回答7:

I've found the easiest (but definitely not the most elegant) way is to use a static class member. eg:

class PassedData
{
    public Bitmap bm1, bm2, etc;

    private PassedData current;

    public static PassedData getCurrent() {return current;}

    public PassedData()
    {
        current = this;
    }
}

Then each activity can reference PassedData.getCurrent().



回答8:

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");

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);