BitmapFactory.decodeStream de Activos devuelve null en Android 7

Cómo decodificar mapas de bits del directorio de activos en Android 7?

Mi aplicación está funcionando bien en las versiones de Android hasta Marshmallow. Con Android 7 falla al cargar imágenes desde el directorio de activos.

Mi código:

private Bitmap getImage(String imagename) { // Log.dd(logger, "AsyncImageLoader: " + ORDNER_IMAGES + imagename); AssetManager asset = context.getAssets(); InputStream is = null; try { is = asset.open(ORDNER_IMAGES + imagename); } catch (IOException e) { // Log.de(logger, "image konnte nicht gelesen werden: " + ORDNER_IMAGES + imagename); return null; } // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, PW, PH); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; // Lesen des Bitmaps in der optimierten Groesse return BitmapFactory.decodeStream(is, null, options); } 

Como resultado (sólo Android 7) BitmapFactory.decodeStream es nulo. Funciona correctamente una vieja API de Android.

En el modo de depuración, veo el siguiente mensaje:

09-04 10: 10: 50.384 6274-6610 / myapp D / skia: — SkAndroidCodec :: NewFromStream devuelto null

¿Puede alguien decirme la razón y cómo corregir la codificación?

Edit: Mientras tanto, encontré que la eliminación de la primera BitmapFactory.decodeStream con inJustDecodeBounds = true conduce a un BitmapFactory.decodeStream con éxito después con inJustDecodeBounds = false. No sé la razón y no sé cómo sustituir la medida de tamaño de mapa de bits.

Creo que estamos en el mismo barco. Mi equipo se quedó en este problema por un tiempo como tú.

Parece ser un problema en BitmapFactory.cpp ( https://android.googlesource.com/platform/frameworks/base.git/+/master/core/jni/android/graphics/BitmapFactory.cpp ) Se ha agregado algún código en Android 7.0 y hecho el problema ocurrió.

 // Create the codec. NinePatchPeeker peeker; std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(streamDeleter.release(), &peeker)); if (!codec.get()) { return nullObjectReturn("SkAndroidCodec::NewFromStream returned null"); } 

Y descubrí que el método BitmapFactory.decodeStream no creó el mapa de bits después de establecer inJustDecodeBounds=false pero cuando intento crear bitmap sin decodificación vinculada. ¡Funciona! El problema es sobre BitmapOptions en que InputStream no se actualiza cuando llamamos a BitmapFactory.decodeStream nuevo.

Así que restablecer ese InputStream antes de decodificar de nuevo

 private Bitmap getBitmapFromAssets(Context context, String fileName, int width, int height) { AssetManager asset = context.getAssets(); InputStream is; try { is = asset.open(fileName); } catch (IOException e) { return null; } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, options); try { is.reset(); } catch (IOException e) { return null; } options.inSampleSize = calculateInSampleSize(options, width, height); options.inJustDecodeBounds = false; return BitmapFactory.decodeStream(is, null, options); } public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } } return inSampleSize; } 

Parece que tenemos que restablecer InputStream cada vez antes de volver a usarlo.

En caso de que esto ayude a alguien, me estaba topando con un problema similar de actualización de código anterior que había trabajado anteriormente para el cambio de tamaño de las imágenes. Mi problema estaba más arriba en la pila donde estaba leyendo datos del archivo de imagen. Hice uso de IOUtils.toByteArray(Reader) , que se ha desaprobado. Cambié a la conversión a una matriz de bytes directamente desde el URI y ahora está funcionando bien. Vea las dos primeras líneas de resizeImage() continuación para el ejemplo de ese nuevo método (El resto del código me permite cambiar el tamaño de la imagen.)

 public static Bitmap resizeImage(Uri imageUri, int targetWidth, int targetHeight) { // Convert the image to a byte array java.net.URI tempUri = new URI(uri.toString()); byte[] imageData = IOUtils.toByteArray(tempUri); // First decode with inJustDecodeBounds=true to check dimensions BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(imageData, 0, imageData.length, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, targetWidth, targetHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; Bitmap reducedBitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length, options); Bitmap resizedBitmap = Bitmap.createScaledBitmap(reducedBitmap, targetWidth, targetHeight, false); return resizedBitmap; } public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a // power of 2 and keeps both height and width larger // than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; } 
  • Xamarin forma la imagen de Android no se está comprimiendo
  • Android - BitmapFactory.decodeByteArray - OutOfMemoryError (OOM)
  • BitmapFactory.decodeResource Bitmap tamaño no original en píxeles
  • En Android cómo decodificar un jpeg en formato cmyk color?
  • Cómo guardar un lienzo en un mapa de bits en Android
  • BitmapFactory devuelve una imagen más grande que una fuente
  • Android PNG a Bitmap - SkImageDecoder :: Factory devuelto null
  • Cómo convertir el formato de imagen NV21 en mapa de bits?
  • BitmapFactory devuelve null aunque existe una imagen
  • Android - OutOfMemory mientras decodifica Bitmap de recursos en Android 5.0
  • Java.lang.OutOfMemoryError en android.graphics.BitmapFactory.decodeResource (BitmapFactory.java:374)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.