web-dev-qa-db-fra.com

comment passez-vous les images (bitmaps) entre les activités Android utilisant des ensembles?

Supposons que je dispose d’une activité pour sélectionner une image dans la galerie et la récupérer sous forme de carte bitmap, comme dans l’exemple suivant: here

Maintenant, je veux transmettre cette carte Bitmap à utiliser dans un ImageView pour une autre activité. Je sais que des lots peuvent être transmis entre les activités, mais comment pourrais-je stocker cette carte BitMap dans le lot?

ou y a-t-il une autre approche que je devrais prendre?

50
damonkashu

Je recommanderais fortement une approche différente.

C'est possible si vous voulez VRAIMENT le faire, mais cela coûte beaucoup de mémoire et est aussi lent. Cela pourrait ne pas fonctionner si vous avez un téléphone plus ancien et un gros bitmap. Vous pouvez simplement le passer comme un extra, par exemple intent.putExtra("data", bitmap). Un bitmap implémente Parcelable, vous pouvez donc le mettre dans un extra. De même, un paquet a putParcelable.

Si vous souhaitez le transmettre entre deux activités, je le stocke dans un fichier. C'est plus efficace et moins de travail pour vous. Vous pouvez créer des fichiers privés dans votre dossier de données à l'aide de MODE_PRIVATE, qui ne sont accessibles à aucune autre application.

48
EboMike

Si vous le transmettez sous forme de parcelle, vous obtiendrez une erreur Java BINDER FAILURE. Ainsi, la solution est la suivante: si le bitmap est petit, par exemple, une vignette, passez sous forme de tableau d'octets et de créer le bitmap à afficher dans l'activité suivante.

dans votre activité d'appel ...

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

... et dans votre activité de réception

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

Comme suggéré par @EboMike, j'ai enregistré le bitmap dans un fichier nommé myImage, dans la mémoire de stockage interne de mon application, qui n'est pas accessible par mes autres applications. Voici le code de cette partie:

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

Ensuite, dans l'activité suivante, vous pouvez décoder ce fichier myImage en bitmap à l'aide du code suivant:

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

Note De nombreuses vérifications de null et de mise à l'échelle des images bitmap sont omises.

22
Illegal Argument

Activité

Pour passer un bitmap entre les activités

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

Et dans la classe d'activité

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

fragment

Pour passer un bitmap entre des fragments

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

Pour recevoir à l'intérieur du SecondFragment

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

Transfert d'un bitmap volumineux (Compresser le bitmap)

Si vous obtenez une transaction de classeur ayant échoué, cela signifie que vous dépassez la mémoire tampon de transaction de classeur en transférant un élément important d'une activité à une autre.

Donc, dans ce cas, vous devez compresser le bitmap en tant que tableau d'octets puis le décompresser dans une autre activité, comme ceci

dans la première activité

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

et dans la seconde activité

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

en premier.Java

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

en seconde.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();
        }
2
Jahh

Le bitmap est Parcelable vous pouvez donc l'ajouter à l'aide de la méthode [putExtra (String, Parcelable)] [2], mais vous n'êtes pas sûr que ce soit une bonne pratique. S'il s'agit de données de grande taille, lieu unique et utilisation des deux activités.

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

2
Sudar Nimalan

Écrivez ce code à partir de l'endroit où vous souhaitez vous engager dans la prochaine activité.

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

Dans la fonction onCreate de NextActivity.class

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

J'ai dû redimensionner le bitmap un peu pour ne pas dépasser la limite de 1 Mo du classeur de transaction. Vous pouvez adapter le 400 à votre écran ou le rendre dynamique, il est juste destiné à être un exemple. Cela fonctionne bien et la qualité est agréable. C'est aussi beaucoup plus rapide que de sauvegarder l'image et de la charger après, mais vous avez une limite de taille.

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;

}

Après avoir récupéré le bmp dans votre nextActivity avec le code suivant:

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

}

J'espère que ma réponse a été utile. Salutations

1
Jan Ziesse

Vous pouvez passer une image en bref sans utiliser un paquet comme celui-ci. Il s'agit du code du fichier .class de l'expéditeur.

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

et c'est le code du fichier de classe du récepteur.

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

Pas besoin de compresser. c'est ça

1
Abdul Qadir