Pregunta

En mi actividad, me cree una Bitmap objeto y, a continuación, tengo que iniciar otra Activity, ¿Cómo puedo pasar esta Bitmap objeto de la sub-actividad (la que va a ser lanzado)?

¿Fue útil?

Solución

Bitmap implementa Parcelable, por lo que siempre podía pasarlo con la intención de:

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

y recuperarlo en el otro extremo:

Intent intent = getIntent(); 
Bitmap bitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");

Otros consejos

En realidad, pasando un mapa de bits como parcelable dará lugar a un error de "JAVA BINDER FALLO". Trate de pasar el mapa de bits como una matriz de bytes y la construcción de ésta para su visualización en la siguiente actividad.

compartí mi solución aquí:
¿cómo se pasa imágenes ( mapas de bits) entre las actividades androide uso de los paquetes?

passsing mapa de bits como parceable en paquete entre la actividad no es una buena idea a causa de la limitación de tamaño de Parceable (1 MB). Puede guardar el mapa de bits en un archivo en el almacenamiento interno y recuperar el mapa de bits almacenado en varias actividades. He aquí algunos ejemplos de código.

Para almacenar un archivo de mapa de bits en myImage en el almacenamiento interno:

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

A continuación, en la siguiente actividad se puede descodificar este archivo myImage a un mapa de bits utilizando el código siguiente:

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

Nota: Una gran cantidad de comprobación de mapa de bits nula y la ampliación de se omite,.

Si la imagen es demasiado grande y no se puede guardar y cargar al almacenamiento, se debe considerar simplemente utilizando una referencia estática global al mapa de bits (dentro de la actividad receptora), que se restablecerá a nulo en onDestory, sólo si "isChangingConfigurations" devuelve true.

Debido Intención tiene límite de tamaño. Yo uso público objeto estático que ver mapa de bits pase desde el servicio de radiodifusión ....

public class ImageBox {
    public static Queue<Bitmap> mQ = new LinkedBlockingQueue<Bitmap>(); 
}

pase en mi servicio

private void downloadFile(final String url){
        mExecutorService.submit(new Runnable() {
            @Override
            public void run() {
                Bitmap b = BitmapFromURL.getBitmapFromURL(url);
                synchronized (this){
                    TaskCount--;
                }
                Intent i = new Intent(ACTION_ON_GET_IMAGE);
                ImageBox.mQ.offer(b);
                sendBroadcast(i);
                if(TaskCount<=0)stopSelf();
            }
        });
    }

Mi BroadcastReceiver

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            LOG.d(TAG, "BroadcastReceiver get broadcast");

            String action = intent.getAction();
            if (DownLoadImageService.ACTION_ON_GET_IMAGE.equals(action)) {
                Bitmap b = ImageBox.mQ.poll();
                if(b==null)return;
                if(mListener!=null)mListener.OnGetImage(b);
            }
        }
    };

Comprimir y Enviar Bitmap

La aceptación de la respuesta se bloqueará cuando el Bitmap es demasiado grande. Creo que es una 1MB límite.El Bitmap debe ser comprimido en un formato de archivo diferente, tales como JPG representado por un ByteArray, a continuación, puede ser de forma segura pasa a través de un Intent.

La aplicación

La función está contenida en un hilo separado mediante Kotlin Corrutinas debido a que el Bitmap la compresión es encadenado después de la Bitmap se crea a partir de una url String.El Bitmap la creación requiere un subproceso independiente con el fin de evitar La aplicación No Responde (ANR) errores.

Los Conceptos Utilizados

  • Kotlin Corrutinas notas.
  • El De carga, Contenido, Error (LCE) el patrón se utiliza a continuación.Si está interesado, usted puede aprender más sobre él en esta charla y video.
  • LiveData se usa para devolver los datos.He compilado mi favorito LiveData de los recursos en estas notas.
  • En Paso 3, toBitmap() es un Kotlin función de extensión exigir que la biblioteca sea añadido a la aplicación de las dependencias.

Código

1.Comprimir Bitmap a JPG ByteArray después de que se ha creado.

Repositorio.kt

suspend fun bitmapToByteArray(url: String) = withContext(Dispatchers.IO) {
    MutableLiveData<Lce<ContentResult.ContentBitmap>>().apply {
        postValue(Lce.Loading())
        postValue(Lce.Content(ContentResult.ContentBitmap(
            ByteArrayOutputStream().apply {
                try {                     
                    BitmapFactory.decodeStream(URL(url).openConnection().apply {
                        doInput = true
                        connect()
                    }.getInputStream())
                } catch (e: IOException) {
                   postValue(Lce.Error(ContentResult.ContentBitmap(ByteArray(0), "bitmapToByteArray error or null - ${e.localizedMessage}")))
                   null
                }?.compress(CompressFormat.JPEG, BITMAP_COMPRESSION_QUALITY, this)
           }.toByteArray(), "")))
        }
    }

ViewModel.kt

//Calls bitmapToByteArray from the Repository
private fun bitmapToByteArray(url: String) = liveData {
    emitSource(switchMap(repository.bitmapToByteArray(url)) { lce ->
        when (lce) {
            is Lce.Loading -> liveData {}
            is Lce.Content -> liveData {
                emit(Event(ContentResult.ContentBitmap(lce.packet.image, lce.packet.errorMessage)))
            }
            is Lce.Error -> liveData {
                Crashlytics.log(Log.WARN, LOG_TAG,
                        "bitmapToByteArray error or null - ${lce.packet.errorMessage}")
            }
        }
    })
}

2.Pasar imagen como ByteArray a través de un Intent.

En este ejemplo se pasa de un Fragmento a un Servicio.Es el mismo concepto, si se comparte entre dos Actividades.

Fragmento.kt

ContextCompat.startForegroundService(
    context!!,
    Intent(context, AudioService::class.java).apply {
        action = CONTENT_SELECTED_ACTION
        putExtra(CONTENT_SELECTED_BITMAP_KEY, contentPlayer.image)
    })

3.Convertir ByteArray de vuelta a Bitmap.

Utils.kt

fun ByteArray.byteArrayToBitmap(context: Context) =
    run {
        BitmapFactory.decodeByteArray(this, BITMAP_OFFSET, size).run {
            if (this != null) this
            // In case the Bitmap loaded was empty or there is an error I have a default Bitmap to return.
            else AppCompatResources.getDrawable(context, ic_coinverse_48dp)?.toBitmap()
        }
    }

Puede ser que sea tarde, pero puede ayudar. En el primer fragmento o actividad de hacer declarar una clase ... por ejemplo

   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        description des = new description();

        if (requestCode == PICK_IMAGE_REQUEST && data != null && data.getData() != null) {
            filePath = data.getData();
            try {
                bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), filePath);
                imageView.setImageBitmap(bitmap);
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
                constan.photoMap = bitmap;
            } catch (IOException e) {
                e.printStackTrace();
            }
       }
    }

public static class constan {
    public static Bitmap photoMap = null;
    public static String namePass = null;
}

A continuación, en la segunda clase / fragmento de hacer esto ..

Bitmap bm = postFragment.constan.photoMap;
final String itemName = postFragment.constan.namePass;

Espero que ayuda.

Puede crear una transferencia de mapa de bits. probar esto ....

En la primera clase:

1) Crear:

private static Bitmap bitmap_transfer;

2) Crear getter y setter

public static Bitmap getBitmap_transfer() {
    return bitmap_transfer;
}

public static void setBitmap_transfer(Bitmap bitmap_transfer_param) {
    bitmap_transfer = bitmap_transfer_param;
}

3) Establecer la imagen:

ImageView image = (ImageView) view.findViewById(R.id.image);
image.buildDrawingCache();
setBitmap_transfer(image.getDrawingCache());

Luego, en la segunda clase:

ImageView image2 = (ImageView) view.findViewById(R.id.img2);
imagem2.setImageDrawable(new BitmapDrawable(getResources(), classe1.getBitmap_transfer()));

Todas las soluciones anteriores no funciona para mí, Envío de mapa de bits como parceableByteArray también genera android.os.TransactionTooLargeException: data parcel size error.

Solución

  1. Guardado el mapa de bits en el almacenamiento interno como:
public String saveBitmap(Bitmap bitmap) {
        String fileName = "ImageName";//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;
    }
  1. y enviar putExtra(String) como
Intent intent = new Intent(ActivitySketcher.this,ActivityEditor.class);
intent.putExtra("KEY", saveBitmap(bmp));
startActivity(intent);
  1. y recibirlo en otra actividad como:
if(getIntent() != null){
  try {
           src = BitmapFactory.decodeStream(openFileInput("myImage"));
       } catch (FileNotFoundException e) {
            e.printStackTrace();
      }

 }


En mi caso, la forma mencionada anteriormente no funcionó para mí. Cada vez que pongo el mapa de bits en el intento, la segunda actividad no se inició. Lo mismo ocurrió cuando pasé el mapa de bits como byte [].

href="http://android-er.blogspot.de/2011/10/share-bitmap-between-activities-as.html" enlace y funcionó como un encanto y muy rápido:

package your.packagename

import android.graphics.Bitmap;

public class CommonResources { 
      public static Bitmap photoFinishBitmap = null;
}

en mi primera acitiviy:

Constants.photoFinishBitmap = photoFinishBitmap;
Intent intent = new Intent(mContext, ImageViewerActivity.class);
startActivity(intent);

Y aquí está el onCreate () de mi segundo Actividad:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bitmap photo = Constants.photoFinishBitmap;
    if (photo != null) {
        mViewHolder.imageViewerImage.setImageDrawable(new BitmapDrawable(getResources(), photo));
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top