Reducir el tamaño de la imagen antes de publicar

Tengo una función para enviar un archivo (imagen de cámara o galería) a un WebService. Me gustaría reducir el tamaño de la imagen de fileUri antes de publicar (50% por ejemplo). El archivo es una galería o imagen de cámara.

Esta es mi función postFile :

 public static void postFile(Context context, String url, String fileUri, AsyncHttpResponseHandler responseHandler) { if (myCookieStore == null) { myCookieStore = new PersistentCookieStore(context); client.setCookieStore(myCookieStore); } File myFile = new File(Uri.parse(fileUri).getPath()); RequestParams params = new RequestParams(); try { params.put("profile_picture", myFile); } catch(FileNotFoundException e) { Log.d("error", "error catch"); } Log.d("absolute url", "" + "*" + getAbsoluteUrl(url) + "*"); client.post(context, getAbsoluteUrl(url), params, responseHandler); } 

Cómo puedo hacer eso ?

No es esta biblioteca, que puede comprimir sus imágenes a kb de mb, es muy potente que he utilizado un montón de veces, funciona cargas de archivos son superfast. enlazar

Snippet: compressedImageFile = Compressor.getDefault(this).compressToFile(actualImageFile);

Utiliza internamente el formato google webp, WebP es un formato de imagen moderno que proporciona una compresión sin pérdidas y pérdidas superior para imágenes en la web. El uso de WebP, webmasters y desarrolladores web puede crear imágenes más pequeñas y más ricas que hacen que la web sea más rápida.

La biblioteca es grande en la compresión del tamaño, hace un trabajo realmente bueno, en los archivos grandes que se basó en mis observaciones, como 2mb para arriba, sin embargo hay algunas fugas de la memoria que necesitas dirigir, resuelvo el mío usando el escape canario, aunque Cada desarrollador siempre debe utilizarlo. En general es increíble bifurcación y uso como por favor.

La imagen que hemos capturado o tomado de la galería es demasiado grande. Ahora el tamaño de la imagen de días supera incluso 10 MB. Por lo tanto, es realmente importante utilizar imágenes comprimidas en la aplicación, ya que podemos enfrentar la excepción de memoria.

Use debajo del código para comprimir la imagen

 // return file name of compressed image from imageUri public String compressImage(String imageUri) { String filePath = getRealPathFromURI(imageUri); Bitmap scaledBitmap = null; BitmapFactory.Options options = new BitmapFactory.Options(); // by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If // you try the use the bitmap here, you will get null. options.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeFile(filePath, options); int actualHeight = options.outHeight; int actualWidth = options.outWidth; // max Height and width values of the compressed image is taken as 816x612 float maxHeight = 816.0f; float maxWidth = 612.0f; float imgRatio = actualWidth / actualHeight; float maxRatio = maxWidth / maxHeight; // width and height values are set maintaining the aspect ratio of the image if (actualHeight > maxHeight || actualWidth > maxWidth) { if (imgRatio < maxRatio) { imgRatio = maxHeight / actualHeight; actualWidth = (int) (imgRatio * actualWidth); actualHeight = (int) maxHeight; } else if (imgRatio > maxRatio) { imgRatio = maxWidth / actualWidth; actualHeight = (int) (imgRatio * actualHeight); actualWidth = (int) maxWidth; } else { actualHeight = (int) maxHeight; actualWidth = (int) maxWidth; } } // setting inSampleSize value allows to load a scaled down version of the original image options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight); // inJustDecodeBounds set to false to load the actual bitmap options.inJustDecodeBounds = false; // this options allow android to claim the bitmap memory if it runs low on memory options.inPurgeable = true; options.inInputShareable = true; options.inTempStorage = new byte[16 * 1024]; try { // load the bitmap from its path bmp = BitmapFactory.decodeFile(filePath, options); } catch (OutOfMemoryError exception) { exception.printStackTrace(); } try { scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight,Bitmap.Config.ARGB_8888); } catch (OutOfMemoryError exception) { exception.printStackTrace(); } float ratioX = actualWidth / (float) options.outWidth; float ratioY = actualHeight / (float) options.outHeight; float middleX = actualWidth / 2.0f; float middleY = actualHeight / 2.0f; Matrix scaleMatrix = new Matrix(); scaleMatrix.setScale(ratioX, ratioY, middleX, middleY); Canvas canvas = new Canvas(scaledBitmap); canvas.setMatrix(scaleMatrix); canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG)); // check the rotation of the image and display it properly ExifInterface exif; try { exif = new ExifInterface(filePath); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, 0); Log.d("EXIF", "Exif: " + orientation); Matrix matrix = new Matrix(); if (orientation == 6) { matrix.postRotate(90); Log.d("EXIF", "Exif: " + orientation); } else if (orientation == 3) { matrix.postRotate(180); Log.d("EXIF", "Exif: " + orientation); } else if (orientation == 8) { matrix.postRotate(270); Log.d("EXIF", "Exif: " + orientation); } scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); } catch (IOException e) { e.printStackTrace(); } FileOutputStream out = null; String filename = getFilename(); try { out = new FileOutputStream(filename); // write the compressed bitmap at the destination specified by filename. scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out); } catch (FileNotFoundException e) { e.printStackTrace(); } return filename; } 

El método getFilename () :: Crea una carpeta en la SDCard utilizada para almacenar las imágenes.

 public String getFilename() { File file = new File(Environment.getExternalStorageDirectory().getPath(), "MyFolder/Images"); if (!file.exists()) { file.mkdirs(); } String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg"); return uriSting; } 

El método getRealPathFromURI (imageUri) :: Da el camino real de la imagen desde su contenido:

 private String getRealPathFromURI(String contentURI) { Uri contentUri = Uri.parse(contentURI); Cursor cursor = getContentResolver().query(contentUri, null, null, null, null); if (cursor == null) { return contentUri.getPath(); } else { cursor.moveToFirst(); int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); return cursor.getString(index); } } 

El método calculateInSampleSize :: calcula un valor adecuado para inSampleSize basado en las dimensiones real y requerida:

 public 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 heightRatio = Math.round((float) height/ (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } final float totalPixels = width * height; final float totalReqPixelsCap = reqWidth * reqHeight * 2; while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) { inSampleSize++; } return inSampleSize; } 

Espero que esto te ayude.

He utilizado este código en muchos proyectos y siempre me da buenos resultados, recuerdo que si elijo una imagen con un tamaño de 5-7MB (imagen de 12/13 cámara MP) este código devuelve una imagen de tamaño 1 MB o menos de 2 MB.

 public static boolean validateUri(Uri uri) { if (uri == null) return false; else { String path = uri.getPath(); return !(uri.equals(Uri.EMPTY) || path == null || path.equals("null")); } } 

Primero necesitamos una imagen completa y girar si es necesario.

 public static Bitmap getFullSizeImage(Context context, Uri uri) { String filePath; if (validateUri(uri) && uri.toString().contains("file")) filePath = uri.getPath(); else filePath = getRealPathFromURI(context, uri, MediaStore.Images.Media.DATA); if (filePath == null) return null; try { int rotation = 0; ExifInterface exifInterface = new ExifInterface(filePath); int exifRotation = exifInterface.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); if (exifRotation != ExifInterface.ORIENTATION_UNDEFINED) { switch (exifRotation) { case ExifInterface.ORIENTATION_ROTATE_180: rotation = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: rotation = 270; break; case ExifInterface.ORIENTATION_ROTATE_90: rotation = 90; break; } } Matrix matrix = new Matrix(); matrix.setRotate(rotation); // you can use other than 400 as required width/height Bitmap sourceBitmap = getBitmapFromPath(400, filePath); if (sourceBitmap == null) return null; return Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), matrix, true); } catch (IOException e) { e.printStackTrace(); } return null; } 

Ahora necesitamos un camino real desde URI

 public static String getRealPathFromURI(Context context, Uri contentUri, String type) { Cursor cursor = null; String path = null; try { // String[] proj = { MediaStore.Images.Media.DATA }; String[] projection = {type}; cursor = context.getContentResolver().query(contentUri, projection, null, null, null); if (cursor == null) return null; int columnIndex = cursor.getColumnIndexOrThrow(type); cursor.moveToFirst(); path = cursor.getString(columnIndex); // we choose image from drive etc. if (path == null) path = getDocumentRealPathFromUri(context, contentUri); } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) cursor.close(); } return path; } 

Si elegimos una imagen de la unidad, etc todavía necesitamos un camino real de URI dado

 public static String getDocumentRealPathFromUri(Context context, Uri contentUri) { Cursor cursor = context.getContentResolver().query(contentUri, null, null, null, null); if (cursor == null) return null; cursor.moveToFirst(); String documentId = cursor.getString(0); documentId = documentId.substring(documentId.lastIndexOf(":") + 1); cursor.close(); cursor = context.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{documentId}, null); if (cursor == null) return null; cursor.moveToFirst(); String path = cursor.getString(cursor .getColumnIndex(MediaStore.Images.Media.DATA)); cursor.close(); return path; } 

Ahora tenemos una trayectoria real de la imagen seleccionada así que podemos conseguir un mapa de bits de esta trayectoria usando tamaño de la muestra

 public static Bitmap getBitmapFromPath(int size, String realPathFromURI) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(realPathFromURI, options); options.inSampleSize = calculateInSampleSizeUsingPower2(options, size, size); options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(realPathFromURI, options); } public static int calculateInSampleSizeUsingPower2(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; } 

En este punto tenemos un mapa de bits comprimido, más aún podemos comprimir de nuevo este mapa de bits si realizamos la operación Base64 en un mapa de bits determinado.

 public static String convertToBase64(Bitmap bitmap) { if (bitmap == null) return null; ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)) { String base64 = encodeToString(byteArrayOutputStream.toByteArray(), DEFAULT); try { byteArrayOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } return base64; } return null; } 

En su extremo cortar puede decodificar Base64 y convertir de nuevo a flujo de archivos y guardar su imagen.

Ejemplo

 Bitmap bitmap = getFullSizeImage(context, selectedPhotoUri); if(bitmap != null){ String base64Image = convertToBase64(bitmap); if (base64Image != null) { RequestParams params = new RequestParams(); try { params.put("title", "your_image_name"); params.put("profile_picture", base64Image); } catch(FileNotFoundException e) { Log.d("error", "error catch"); } } } 

Nota Si no desea realizar Base64 puede utilizar su mapa de bits para convertir en flujo y enviarlo a su servidor.

Utilice éste para cambiar el ancho y la altura de la imagen

 public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) { int width = bm.getWidth(); int height = bm.getHeight(); float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false); return resizedBitmap; } 

Usted puede utilizar éste para el cambio el tamaño … Éste es el mejor ejemplo …..

  private Bitmap decodeFile(File f){ try { //Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(new FileInputStream(f),null,o); //The new size we want to scale to final int REQUIRED_SIZE=70; //Find the correct scale value. It should be the power of 2. int scale=1; while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE) scale*=2; //Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize=scale; return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); } catch (FileNotFoundException e) {} return null; } 

Intente esta función. Reducirá el tamaño del mapa de bits a 512 si su ancho o altura es mayor que 512

 public static Bitmap resizeBitmap(Bitmap bm) { if (bm.getWidth() > maxSize || bm.getHeight() > maxSize) { if (bm.getWidth() > bm.getHeight()) { newWidth = maxSize; newHeight = (bm.getHeight() * maxSize) / bm.getWidth(); bm = Bitmap.createScaledBitmap(bm, newHeight, newWidth, true); return bm; } else { newHeight = maxSize; newWidth = (bm.getWidth() * maxSize) / bm.getHeight(); bm = Bitmap.createScaledBitmap(bm, newHeight, newWidth, true); return bm; } } return bm; } 

Sólo tiene que pasar el mapa de bits a este método.

El método para obtener el mapa de bits de URI es

 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 8; bitmap = BitmapFactory.decodeFile(fileUri.getPath(), options); 

Si la imagen de la cámara es JPEG, puede utilizar el método de compresión Bitmap, como:

 Bitmap bitmap = BitmapFactory.decodeStream(...uri); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { int compression_factor = 50; // represents 50% compression bitmap.compress(Bitmap.CompressFormat.JPEG, compression_factor, baos); byte[] image = baos.toByteArray(); // now update web service asynchronously... ... } finally { baos.close(); } 

Convertir la imagen en mapa de bits a continuación, utilice el método a continuación

  public static Bitmap scaleBitmap(Bitmap bitmap, int newWidth, int newHeight) { Bitmap scaledBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888); float scaleX = newWidth / (float) bitmap.getWidth(); float scaleY = newHeight / (float) bitmap.getHeight(); float pivotX = 0; float pivotY = 0; Matrix scaleMatrix = new Matrix(); scaleMatrix.setScale(scaleX, scaleY, pivotX, pivotY); Canvas canvas = new Canvas(scaledBitmap); canvas.setMatrix(scaleMatrix); canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG)); return scaledBitmap; } 
  • Android Studio no puede resolver ninguna dependencia
  • ¿Debo entrar en Android Studio o debo seguir con Eclipse?
  • Cómo configurar la configuración de SONAR para el complemento de sonar intellij para Android Studio?
  • IInAppBillingService.aidl no puede generar archivos Java en Android Studio
  • Cómo utilizar Google Plus Integration en Android Studio
  • Android Studio accidente (aapt.exe devuelve 42) cuando puse el archivo PNG en la carpeta dibujable
  • Ctrl + N acceso directo - Android Studio
  • Proyecto Ui Automator 2.0 en Android Studio
  • Gradle: El nombre de archivo, el nombre de directorio o la sintaxis de etiquetas de volumen es incorrecto
  • Importar proyecto android de netbeans en android studio
  • Gradle: cómo agregar un frasco para construir pero no para exportarlo
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.