Comment passer des images (bitmaps) entre les activités android en utilisant des paquets?
supposons que j'ai une activité pour sélectionner une image à partir de la galerie, et la récupérer comme une image BitMap, tout comme l'exemple: ici
maintenant, je veux passer ce BitMap pour être utilisé dans une ImageView pour une autre activité. Je sais que les paquets peuvent être passés d'une activité à l'autre, mais comment puis-je stocker cette BitMap dans le paquet?
ou y a-t-il une autre approche que je devrais adopter?
9 réponses
je recommande vivement une approche différente.
C'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 le passer comme un supplément, par exemple intent.putExtra("data", bitmap)
. Un Bitmap implémente séparable, de sorte que vous pouvez le mettre dans un supplément. De même, un paquet a putParcelable
.
si vous voulez passer entre les activités, je le stockerais 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 en utilisant MODE_PRIVATE qui ne sont accessibles à aucune autre application.
si vous le Passez comme un séparable, vous êtes lié à obtenir une erreur D'échec de classeur JAVA. Donc, la solution est ceci: Si l'image est petite, comme, par exemple, une vignette, passer comme un tableau d'octets et de construire l'image bitmap à afficher dans l'activité suivante. Par exemple:
dans votre activité...
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);
}
comme suggéré par @EboMike j'ai enregistré le bitmap dans un fichier nommé myImage dans le stockage interne de mon application 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;
}
puis dans l'activité suivante vous pouvez décoder ce fichier myImage en bitmap en utilisant le code suivant:
Bitmap bitmap = BitmapFactory.decodeStream(context
.openFileInput("myImage"));//here context can be anything like getActivity() for fragment, this or MainActivity.this
Note un grand nombre de vérification pour null et la mise à l'échelle bitmap est omis.
activité
pour passer une bitmap entre les Activites
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 une image entre les Fragments
SecondFragment fragment = new SecondFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap);
fragment.setArguments(bundle);
pour recevoir à l'intérieur du second fragment
Bitmap bitmap = getArguments().getParcelable("bitmap");
transfer large bitmap (Compress bitmap)
si vous avez échoué à une opération de reliure, cela signifie que vous dépassez le tampon de transaction de reliure en transférant un élément important d'une activité à une autre.
donc dans ce cas vous devez compresser le bitmap comme un tableau d'octets et ensuite 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 deuxième activité
byte[] bytes = getIntent().getByteArrayExtra("bitmapbytes");
Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
Bitmap est divisible ainsi vous pouvez ajouter en utilisant la méthode [putExtra(chaîne,divisible)][2], mais pas sûr que ce soit une bonne pratique, S'il s'agit de données de grande taille, il est préférable de stocker dans un seul endroit et d'utiliser à partir des deux activités.
[2]: http://developer.android.com/reference/android/content/Intent.html#putExtra (java.lang.Chaîne , android.OS.Séparable)
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();
}
j'ai dû changer le bitmap un peu pour ne pas dépasser la limite de 1mb du classeur de transactions. Vous pouvez adapter le 400 votre écran ou le faire dinamic il est juste destiné à être un exemple. Il 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 la limitation 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é la bmp dans votre activité suivante 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
écrivez ce code à partir de là où vous voulez que L'intention 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);
En Fonction onCreate de NextActivity.classe
Bitmap hotel_image;
Intent intent = getIntent();
hotel_image= intent.getParcelableExtra("Image");
vous pouvez passer l'image en bref sans utiliser bundle comme ceci C'est le code de l'expéditeur .fichier de classe
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 voici le code de la 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 tout