studio programacion herramientas fundamentos con avanzado aplicaciones android bitmap image-uploading image-resizing

programacion - manual de android en pdf



Android: reduce el tamaƱo del archivo de imagen (2)

Tengo un archivo de imagen URI, y quiero reducir su tamaño para subirlo. El tamaño del archivo de imagen inicial depende de un dispositivo móvil a otro (puede ser de 2MB, como puede ser 500KB), pero quiero que el tamaño final sea de aproximadamente 200KB, para que pueda cargarlo.
Por lo que leí, tengo (al menos) 2 opciones:

  • Usando BitmapFactory.Options.inSampleSize , para submuestrear la imagen original y obtener una imagen más pequeña;
  • Usando Bitmap.compress para comprimir la imagen que especifica la calidad de compresión.

¿Cuál es la mejor opción?

Estaba pensando en redimensionar inicialmente el ancho / alto de la imagen hasta que el ancho o la altura estén por encima de 1000px (algo así como 1024x768 u otros), luego comprimir la imagen con calidad decreciente hasta que el tamaño del archivo sea superior a 200KB. Aquí hay un ejemplo:

int MAX_IMAGE_SIZE = 200 * 1024; // max final file size Bitmap bmpPic = BitmapFactory.decodeFile(fileUri.getPath()); if ((bmpPic.getWidth() >= 1024) && (bmpPic.getHeight() >= 1024)) { BitmapFactory.Options bmpOptions = new BitmapFactory.Options(); bmpOptions.inSampleSize = 1; while ((bmpPic.getWidth() >= 1024) && (bmpPic.getHeight() >= 1024)) { bmpOptions.inSampleSize++; bmpPic = BitmapFactory.decodeFile(fileUri.getPath(), bmpOptions); } Log.d(TAG, "Resize: " + bmpOptions.inSampleSize); } int compressQuality = 104; // quality decreasing by 5 every loop. (start from 99) int streamLength = MAX_IMAGE_SIZE; while (streamLength >= MAX_IMAGE_SIZE) { ByteArrayOutputStream bmpStream = new ByteArrayOutputStream(); compressQuality -= 5; Log.d(TAG, "Quality: " + compressQuality); bmpPic.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpStream); byte[] bmpPicByteArray = bmpStream.toByteArray(); streamLength = bmpPicByteArray.length; Log.d(TAG, "Size: " + streamLength); } try { FileOutputStream bmpFile = new FileOutputStream(finalPath); bmpPic.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpFile); bmpFile.flush(); bmpFile.close(); } catch (Exception e) { Log.e(TAG, "Error on saving file"); }

Hay una mejor manera de hacerlo? ¿Debo intentar seguir usando los 2 métodos o solo uno? Gracias


Al utilizar Bitmap.compress() solo especifica el algoritmo de compresión y, por cierto, la operación de compresión lleva bastante tiempo. Si necesita jugar con tamaños para reducir la asignación de memoria para su imagen, es necesario usar la escala de su imagen usando Bitmap.Options , Bitmap.Options computando los límites del mapa de bits y luego decodificándolo al tamaño especificado.

La mejor muestra que encontré en es esta .


La mayoría de las respuestas que encontré fueron solo piezas que tuve que juntar para obtener un código de trabajo, que se publica a continuación.

public void compressBitmap(File file, int sampleSize, int quality) { try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = sampleSize; FileInputStream inputStream = new FileInputStream(file); Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, options); inputStream.close(); FileOutputStream outputStream = new FileOutputStream("location to save"); selectedBitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream); outputStream.close(); long lengthInKb = photo.length() / 1024; //in kb if (lengthInKb > SIZE_LIMIT) { compressBitmap(file, (sampleSize*2), (quality/4)); } selectedBitmap.recycle(); } catch (Exception e) { e.printStackTrace(); } }

2 parámetros sampleSize y calidad juega un papel importante

sampleSize se utiliza para submuestrear la imagen original y devolver una imagen más pequeña , es decir,
SampleSize == 4 devuelve una imagen que es 1/4 del ancho / alto del original.

la calidad se utiliza para indicar el compresor , el rango de entrada está entre 0-100. 0 significa comprimir para tamaño pequeño, 100 lo que significa comprimir para la calidad máxima