57 votes

Comment passez-vous les images (bitmaps) entre les activités Android à l'aide de bundles?

Supposons que j'ai une activité de sélectionner une image dans la galerie, et de les récupérer sous forme de BitMap, juste comme dans l'exemple: ici

Maintenant, je veux passer cette image doit être utilisé dans une ImageView pour une autre activité. Je suis conscient des faisceaux peut être transmis entre les activités, mais comment pourrais-je conserver ce BitMap dans le bundle?

ou est-il une autre approche que je dois prendre?

56voto

EboMike Points 39257

Je recommande fortement une approche différente.

Il est possible si vous voulez VRAIMENT le faire, mais il coûte beaucoup de mémoire et est également lente. Il pourrait ne pas fonctionner si vous avez un vieux téléphone et un gros bitmap. Vous pouvez simplement passer comme un extra, par exemple intent.putExtra("data", bitmap). Une image Bitmap implémente Parcelable, de sorte que vous pouvez les mettre dans une supplémentaire. De même, un bundle a putParcelable.

Si vous voulez passer entre les deux activités, je voudrais stocker dans un fichier. C'est plus efficace, et moins de travail pour vous. Vous pouvez créer des fichiers dans votre dossier de données à l'aide de MODE_PRIVATE qui ne sont pas accessibles à n'importe quelle autre application.

45voto

Harlo Holmes Points 1763

Si vous le transmettez en tant que Parcelable, vous obtiendrez une erreur JAVA BINDER FAILURE. La solution est donc la suivante: si le bitmap est petit, par exemple une vignette, transmettez-le sous forme de tableau d'octets et créez le bitmap pour l'affichage dans l'activité suivante. Par exemple:

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

24voto

Illegal Argument Points 4244

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 à 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
 

Remarque: Une grande partie de la vérification de null et de la mise à l'échelle des images bitmap est omise.

2voto

Sudar Nimalan Points 1956

Bitmap est Parcelable de sorte que vous pouvez ajouter à l'aide de [putExtra(String,Parcelable)][2] méthode, Mais pas sûr que c'est une bonne pratique, Si elle est de grande taille de données, il est préférable de les stocker dans un lieu unique et l'utilisation de ces deux activités.

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

1voto

Jan Ziesse Points 21

J'ai dû redimensionner l'image bitmap d'un peu de ne pas dépasser la limite de 1 mo de la transaction classeur. Vous pouvez adapter les 400 de la de votre écran ou de le rendre dynamique, c'est juste censé être un exemple. Il fonctionne très bien et la qualité est belle. Il est aussi beaucoup plus rapide que l'enregistrement de l'image et de le charger après, mais vous avez la limitation de la 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 la récupération de la 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é quelque peu utile. Salutations

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X