Pasar datos de mapa de bits de Android dentro de la actividad usando Intent en Android
Tengo una variable de mapa de bits nombrada bmp
en Actividad1 y quiero enviar el mapa de bits a Actividad2
El siguiente es el código que uso para pasarlo con la intención.
Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",bmp);
startActivity(in1);
Y en Actividad2 intento acceder al mapa de bits usando el siguiente código
Bundle ex = getIntent().getExtras();
Bitmap bmp2 = ex.getParceable("image");
ImageView result = (ImageView)findViewById(R.Id.imageView1);
result.setImageBitmap(bmp);
La aplicación se ejecuta sin excepción pero no da el resultado esperado
Conviértalo en una matriz de bytes antes de agregarlo al intent, enviarlo y decodificarlo.
//Convert to byte array
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",byteArray);
Luego en la Actividad 2:
byte[] byteArray = getIntent().getByteArrayExtra("image");
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
editar
Pensé que debería actualizar esto con las mejores prácticas:
En su primera actividad, debe guardar el mapa de bits en el disco y luego cargarlo en la siguiente actividad. Asegúrate de reciclar tu mapa de bits en la primera actividad para prepararlo para la recolección de basura:
Actividad 1:
try {
//Write file
String filename = "bitmap.png";
FileOutputStream stream = this.openFileOutput(filename, Context.MODE_PRIVATE);
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
//Cleanup
stream.close();
bmp.recycle();
//Pop intent
Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image", filename);
startActivity(in1);
} catch (Exception e) {
e.printStackTrace();
}
En la Actividad 2, cargue el mapa de bits:
Bitmap bmp = null;
String filename = getIntent().getStringExtra("image");
try {
FileInputStream is = this.openFileInput(filename);
bmp = BitmapFactory.decodeStream(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
A veces, el mapa de bits puede ser demasiado grande para codificar y decodificar o pasarlo como una matriz de bytes en la intención. Esto puede causar OOM o una mala experiencia de UI.
Sugiero considerar colocar el mapa de bits en una variable estática de la nueva actividad (la que lo usa) que cuidadosamente será nula cuando ya no lo necesite (es decir, en onDestroy pero solo si "isChangingConfigurations" devuelve falso).
Simplemente podemos pasar solo el Uri del mapa de bits en lugar de pasar el objeto de mapa de bits. Si el objeto Bitmap es grande, causará problemas de memoria.
Primera Actividad.
intent.putExtra("uri", Uri);
Desde SecondActivity recuperamos el mapa de bits.
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(),Uri.parse(uri));
Código Kotlin para enviar mapa de bits a otra actividad por intención:
1- en Primera Actividad:
val i = Intent(this@Act1, Act2::class.java)
var bStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 50, bStream)
val byteArray = bStream.toByteArray()
i.putExtra("image", byteArray )
startActivity(i)
2- En la Actividad dos (Lea la imagen de mapa de bits):
var bitmap : Bitmap? =null
if (intent.hasExtra("image")){
//convert to bitmap
val byteArray = intent.getByteArrayExtra("image")
bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
}
3- si necesita configurarlo como fondo para una vista, como ConstraintLayout o...:
if (bitmap != null) {
//Convert bitmap to BitmapDrawable
var bitmapDrawable = BitmapDrawable( resources , bitmap)
root_constraintLayout.backgroundDrawable = bitmapDrawable
}
crear una clase singleton para almacenar datos de mapa de bits
public final class BitmapData {
private static final BitmapData bitmapData = new BitmapData();
private Bitmap bitmap;
private BitmapData() {
}
public static BitmapData getInstance() {
return bitmapData;
}
public Bitmap getBitmap() {
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
En la primera actividad puedes configurarlo así.
BitmapData.getInstance().setBitmap(bitmap);
y en segunda actividad
Bitmap bitmap = BitmapData.getInstance().getBitmap();
Nota: verifique el valor nulo