studio resource imagen from example create convertir android bitmap

android - resource - BitmapFactory.decodeFile out of memory with images 2400x2400



draw bitmap in android studio (3)

NO cargue la imagen como un mapa de bits, conviértala en una matriz y luego envíela.

en lugar:

Léalo como un archivo, en formato JPG. Utilice la matriz de bytes de archivos para codificarla y enviar el archivo.

Cargarlo en un mapa de bits, causará innecesariamente grandes problemas de memoria. Una imagen, representada en formato de mapa de bits, tomará ~ 20x o más memoria que la necesaria.

En el lado del servidor, también deberá tratarlo como un archivo. en lugar de un mapa de bits.

Aquí hay un enlace para cargar un archivo a byte []: elegante forma de leer el archivo en la matriz de bytes [] en Java

Necesito enviar una imagen de un archivo a un servidor. El servidor solicita la imagen en una resolución de 2400x2400.

Lo que estoy tratando de hacer es:

1) Obtenga un mapa de bits utilizando BitmapFactory.decodeFile utilizando el inSampleSize correcto.

2) Comprimir la imagen en JPEG con una calidad del 40%.

3) Codificar la imagen en base64.

4) Enviado al servidor

No puedo lograr el primer paso, arroja una excepción de memoria. Estoy seguro de que inSampleSize es correcto, pero supongo que incluso con inSampleSize el mapa de bits es enorme (alrededor de 30 MB en DDMS).

¿Alguna idea de cómo puede hacerlo? ¿Puedo hacer estos pasos sin crear un objeto de mapa de bits? Me refiero a hacerlo en el sistema de archivos en lugar de memoria RAM.

Este es el código actual:

// The following function calculate the correct inSampleSize Bitmap image = Util.decodeSampledBitmapFromFile(imagePath, width,height); // compressing the image ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 40, baos); // encode image String encodedImage = Base64.encodeToString(baos.toByteArray(),Base64.DEFAULT)); 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) { // Calculate ratios of height and width to requested height and width final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } public static Bitmap decodeSampledBitmapFromFile(String path,int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(path,options); }


puede omitir ARGB_8888, y usar RGB_565 en su lugar, y luego difuminar las imágenes para preservar la buena calidad

BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = false; options.inPreferredConfig = Config.RGB_565; options.inDither = true;


tienes que usar BitmapFactory.Options con inJustDecodeBounds establecido en true. De esta manera, puede cargar información sobre el mapa de bits y calcular el valor para inSampleSize su muestreo (por ejemplo, inSampleSize )