Proceso para comprimir una imagen para subirla a un servidor en Android

Quiero escribir mi propio código para comprimir una imagen antes de subirla al servidor.

He visto muchos mensajes en SO como este y hay muchos otros puestos también, pero en todas partes hay sólo muestras de código. En realidad no se explica en ninguna parte. No soy capaz de entender del código dado.

Sólo quiero saber sobre el enfoque general para comprimir imágenes para que pueda empezar a escribir código por mí mismo.

No estoy buscando el código, sólo los pasos que una persona debe seguir para comprimir una imagen. (Como un algoritmo se escribe antes de escribir el programa es decir, pseudocódigo)

Creo que la respuesta de Chetan Joshi es la más cercana hasta ahora. Pero para explicar un poco más,

"Comprimir" una imagen y "escalar" (cambiar el tamaño) de una imagen son diferentes. Dado que simplemente desea reducir el ancho de banda (kb / Mb) a través de la red cuando se carga en el servidor, es más probable que hablen de "escalado", ya que hará la mayor diferencia con el tamaño de la imagen.

Tenga en cuenta, como en otras respuestas de Android, tendrá que trabajar con Bitmaps . Necesita utilizar las llamadas API asociadas con Bitmaps para hacer lo que desea.

Punto de partida:

Si usted permite que su aplicación tome una foto usando la cámara o escoge de la galería, obtendrá un Uri que le permite abrir un InputStream así:

InputStream is = getContext().getContentResolver().openInputStream(photoUri); 

Ese es el primer paso. La siguiente parte es el pseudocódigo en el que desea algo como esto:

  1. Obtener un InputStream de la foto / imagen seleccionada. Esto es sólo una secuencia de bytes que representan la imagen.
  2. Decodificar la secuencia en un Bitmap utilizando BitmapFactory.decodeStream(InputStream src)
  3. Escala (redimensiona) el mapa de bits utilizando Bitmap.createScaledBitmap(src, dstWidth, dstHeight, filter); . Tendrás que decidir el ancho de destino y la altura de destino que deseas. Ver el siguiente conjunto de pseudocódigo.
  4. Comprimir el mapa de bits utilizando imageFormat.getBitmapCompressFormat(), 100, output) donde salida es una instancia de ByteArrayOutputStream
  5. Ahora puede llamar a output.toByteArray(); Para obtener los bytes.
  6. Los bytes son los que desea enviar al servidor.

Tenga en cuenta cómo elegir el ancho y la altura del destino a escala para:

  1. Decida sobre una altura máxima y un ancho máximo, digamos 240 x 240. Usted estará comparando esto con la altura real y el ancho real del mapa de bits.
  2. Si es demasiado alto (altura real> altura máxima), calcule un factor de escala que sea altura máxima / altura real
  3. Si es demasiado ancho (anchura real> ancho máximo), calcule un factor de escala que sea el ancho máximo / ancho real
  4. Su factor de escala real es el mínimo de estos dos factores de escala
  5. Devolver el factor de escala de altura real * y el ancho real * factor de escala

En conjunto, el proceso de alto nivel es algo así:

  1. Abrir un flujo de bytes de la imagen
  2. Convertir los bytes en un mapa de bits
  3. Escala del mapa de bits
  4. Comprimir el mapa de bits
  5. Convertir el mapa de bits de nuevo en bytes

La compresión de imágenes en Android significa que estamos trabajando con Bitmaps, mientras que estamos comprimiendo cualquier imagen grande para bajar, entonces tenemos método de compresión en la clase Bitmap, pero si la diferencia entre el tamaño del mapa de bits original y bitmap deseado es demasiado alto, entonces la calidad del mapa de bits siempre reducido.

Para comprimir el mapa de bits con alta calidad tenemos que utilizar el proceso recursivo para comprimir cualquier mapa de bits comprimiendo cualquier mapa de bits directamente desde el ancho de altura original a la altura deseada y el ancho, debemos comprimir la imagen con 3 a 5 pasos por ejemplo si nuestro tamaño de imagen es 1000x1000 y quería El ancho y la altura son 300x300 entonces aplicamos el proceso recursivo para hacer esto como abajo:

 1000 x 1000 850 x 850 650 x 650 300 x 300 

De esta manera nuestra calidad Bitmap no se reduce, pero asegúrese de no crear nuevo objeto de mapa de bits cada vez que utilice el mismo objeto de mapa de bits para asignar mapa de bits comprimido de lo contrario debe enfrentar el problema OutOfmemmory.

Usted puede apenas utilizar el androide sdk – bitmap.compress ();

 ByteArrayOutputStream bos = new ByteArrayOutputStream(); if (myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos)) { //image is now compressed into the output stream uploadImage(bos); } else { //compress failed } 

Usted puede comprobar siempre el código de fuente del androide para aprender más sobre él pero si usted es un desarrollador androide pienso poner el tiempo en aprender cómo comprimir no debe ser su foco principal especialmente cuando usted tiene una solución tan fácil para él, si usted Todavía pienso que usted lo haría yo habría comenzado aprendiendo cómo se comprime primero de los archivos, después me trasladaría a las imágenes y solamente entonces habría mirado el código de fuente

Puesto que usted no está buscando realmente el código, aquí es un recurso fantástico para aprender sobre el proceso del pensamiento detrás de la compresión de la imagen

Hay una variedad de algoritmos que hacen uso de diferentes técnicas para aprovechar las diferentes variables involucradas. La complejidad computacional, el espacio de almacenamiento, la ración de compresión y la retención de la calidad de imagen son factores que estos diferentes algoritmos (o formatos de archivo) buscan optimizar, a menudo favoreciendo un atributo sobre el otro. Png PNG vs JPEG para la calidad frente al espacio

Java proporciona API de ImageIO que pueden ayudar a comprimir una imagen con su elección de calidad y factor de compresión. ImageWriter y ImageWriteParam proporcionan las capacidades mencionadas fuera de la caja.

¿Está planeando escribir su propia API para otras razones personalizadas a su requerimiento?

Si no está usando java fuera de la caja de API, el enfoque de alto nivel podría ser: 1) Leer el archivo de imagen. 2) usar ImageIO, conseguir el ImageWriter basado en el tipo de la imagen como (jpeg, png etc.) 3) Consiga el objeto ImageWriteParam del escritor y fije los params de la compresión según su requisito. 4) escribe la imagen.

Hazme saber si no funciona para ti.

El código de su enlace describe no tanto la compresión, sino más bien el muestreo de la imagen con una menor densidad y la reducción de escala. Así que no es realmente la compresión, sino una reducción de la calidad (número de píxeles y tamaño) para hacerlo más pequeño. Los buenos algoritmos de compresión encontrarán generalmente una manera de ahorrar la imagen de una manera que utilice menos espacio sin comprometer demasiado la calidad (con matemáticas y materia).

Recortar la imagen y luego enviar a server.Its funcionando bien,

Añadir dependencia en gradle,

 compile 'com.soundcloud.android:android-crop:1.0.1@aar' 

Galería Intención,

 private static final int PICK_FROM_FILE = 3; private Uri mImageCaptureUri=null; File sdCard = Environment.getExternalStorageDirectory(); String pathName; File filepath; Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(i, PICK_FROM_FILE); protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != RESULT_OK) return; switch (requestCode) { case PICK_FROM_FILE: mImageCaptureUri = data.getData(); // METHOD FOR CROP beginCrop(mImageCaptureUri); System.out.println("CHECK_GALLERY_path :" + mImageCaptureUri); break; case Crop.REQUEST_CROP: handleCrop(resultCode, data); break; } } private void beginCrop(Uri source) { Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped")); Crop.of(source, destination).start(this); } private void handleCrop(int resultCode, Intent result) { if (resultCode == RESULT_OK) { mImageCaptureUri = Crop.getOutput(result); pathName = mImageCaptureUri.getPath(); //uploadImageToServer(); // getImageUri(mImageCaptureUri); Picasso.with(Activity_My_Account.this).load(mImageCaptureUri).into(getimage); //IMAGE SAVE TO STORAGE getImageUri(mImageCaptureUri); System.out.println("path_name+++" + mImageCaptureUri); } else if (resultCode == Crop.RESULT_ERROR) { Toast.makeText(this, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show(); } } private void getImageUri(Uri mImageCaptureUri) { Bitmap photo = null; try { InputStream image_stream = getContentResolver().openInputStream(mImageCaptureUri); java.util.Date date = new java.util.Date(); pathName = sdCard + "/" + "LEUF"; File myDir = new File(pathName); System.out.println("GET_CHECK_PATH_NAME :" + pathName); myDir.mkdirs(); Random generator = new Random(); int n = 10000; n = generator.nextInt(n); String fname = "Image-" + n + ".jpg"; File file = new File(myDir, fname); // if (file.exists()) file.delete(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); Bitmap bitmapOrg = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(image_stream), 350, 350, false); photo.compress(Bitmap.CompressFormat.JPEG, 100, bytes); filepath=file; try { // file.createNewFile(); FileOutputStream fo = new FileOutputStream(file); fo.write(bytes.toByteArray()); fo.flush(); fo.close(); } catch (IOException e) { e.printStackTrace(); } //here call to upload image to server public void UploadProfilePic(filepath){ } } catch (FileNotFoundException e) { e.printStackTrace(); } } 
  • Leer y mostrar texto de mensaje entrante android
  • Quitar la sombra de ActionBar en Android L (API 21)
  • Cómo convertir un SparseArray a ArrayList?
  • Transmisión de audio y vídeo desde Android a PC / web.
  • Alinea el texto dentro de un botón en Android
  • Intentando ejecutar pruebas triviales de JUnit para Android. Obtención: "Error de prueba: No hay resultados de prueba" ¿Qué me falta?
  • Envío de mensajes OSC (control de sonido abierto) desde una aplicación android
  • java.util.regex.PatternSyntaxException: Error de sintaxis en patrón regex cerca de índice
  • Cookies persistentes de Android HttpClient
  • Acceder usando la cuenta de Google en Android
  • Trigger galaxia S4 sensor de infrarrojos de desarrollo de aplicaciones?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.