Bitmap comprimido con calidad = 100 tamaño de archivo mayor que original
Estoy intentando enviar una imagen a un servidor. Antes de enviarlo, estoy reduciendo su tamaño y calidad, y luego solucionando cualquier problema de rotación. Mi problema es que, después de girar la imagen, cuando la guarde, el archivo es más grande que antes. Antes de que el tamaño de rotación fuera 10092 y después de la rotación se 54226
// Scale image to reduce it Bitmap reducedImage = reduceImage(tempPhotoPath); // Decrease photo quality FileOutputStream fos = new FileOutputStream(tempPhotoFile); reducedImage.compress(CompressFormat.JPEG, 55, fos); fos.flush(); fos.close(); // Check and fix rotation issues Bitmap fixed = fixRotation(tempPhotoPath); if(fixed!=null) { FileOutputStream fos2 = new FileOutputStream(tempPhotoFile); fixed.compress(CompressFormat.JPEG, 100, fos2); fos2.flush(); fos2.close(); } public Bitmap reduceImage(String originalPath) { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; o.inPurgeable = true; o.inInputShareable = true; BitmapFactory.decodeFile(originalPath, o); // The new size we want to scale to final int REQUIRED_SIZE = 320; // Find the correct scale value. It should be the power of 2. int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while (true) { if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) { break; } width_tmp /= 2; height_tmp /= 2; scale *= 2; } // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inPurgeable = true; o2.inInputShareable = true; o2.inSampleSize = scale; Bitmap bitmapScaled = null; bitmapScaled = BitmapFactory.decodeFile(originalPath, o2); return bitmapScaled; } public Bitmap fixRotation(String path) { Bitmap b = null; try { //Find if the picture is rotated ExifInterface exif = new ExifInterface(path); int degrees = 0; if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("6")) degrees = 90; else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("8")) degrees = 270; else if(exif.getAttribute(ExifInterface.TAG_ORIENTATION).equalsIgnoreCase("3")) degrees = 180; if(degrees > 0) { BitmapFactory.Options o = new BitmapFactory.Options(); o.inPurgeable = true; o.inInputShareable = true; Bitmap bitmap = BitmapFactory.decodeFile(path, o); int w = bitmap.getWidth(); int h = bitmap.getHeight(); Matrix mtx = new Matrix(); mtx.postRotate(degrees); b = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true); } } catch(Exception e){e.printStackTrace();} return b; }
- Guardar hardware acelerado android lienzo como mapa de bits
- Dando dibujo / Pintura / Ahorro de múltiples mapas de bits
- Mostrar imagen grande de la tarjeta SD en Android
- Grilla 2D Array en lienzo de dibujo
- ¿Cómo crear Bitmap de la imagen de buffer de bytes en grises?
- Rellenar los datos en un mapa de bits de Android tan pronto como sea posible desde C
- Cargar un recurso a un mapa de bits mutable
- Aplicación de una superposición (filtro de imagen) a un mapa de bits
- Recorte de rectángulo redimensionable de Android
- Borde sobre un mapa de bits con esquinas redondeadas en Android
- ¿Cómo hacer efecto de resplandor alrededor de un mapa de bits?
- Evitar las descargas de la aplicación de la tableta
- Cómo rotar el mapa de bits correctamente?
Lo está comprimiendo con diferentes medidas de calidad. Después de la rotación, usted está utilizando la calidad 100, así que va a ser un archivo más grande que el anterior, con calidad 55.
Cuando comprime una imagen, no importa cuál sea el tamaño / calidad del archivo actual. Eso no tiene un impacto real en el resultado. La compresión a 55 calidad, seguida por 100 calidad, no da como resultado un archivo con el mismo tamaño que una simple compresión de 55 calidad. Se traduce en un archivo con el tamaño de la compresión de calidad 100, porque eso es lo último que se le hace.
Para su código específico, no estoy seguro de ver la razón detrás de comprimir dos veces de todos modos. La compresión (tamaño de archivo) no es lo que causaba los problemas de MOO al girar, las dimensiones de la imagen eran muy probablemente el culpable. Reducir la imagen antes de girar debe arreglar eso, no hay necesidad de guardar un archivo temporal.
Todo lo que necesitas hacer es ejecutar reduceImage()
, y luego seguirlo con fixRotation()
. Corrige el método de rotación para que acepte un Bitmap
de Bitmap
lugar de una ruta, por lo que no es necesario guardar el archivo entre. Finalmente, guárdelo / comprimelo en cualquier calidad que usted desee.
Si necesita el archivo temporario por alguna razón, utilice PNG para la primera compresión. De esta manera es sin pérdidas, por lo que al recomprimir la imagen final, no habrá utilizado JPG (pérdida) dos veces en una calidad baja.
- Quitar y agregar la página a FragmentPagerAdapter
- ¿Mejora el rendimiento de la vista personalizada SurfaceView-dervied?