Compresión de imagen como Whatsapp y otros mensajeros en Android

Estoy utilizando el siguiente código para la compresión de imágenes.

El código comprime archivos de imagen que son mayores de 2 MB.

Pero este código toma tiempo y la calidad de la imagen permanece pura.

public static String compressImage(String imagePath, Context context) { String resizeImagePath = null; String filePath = imagePath; CustomLogHandler.printDebug(TAG, "resizeImagePath:" + imagePath); Bitmap scaledBitmap = null; int imageScal = 1; // File size greater then 2mb DecimalFormat df = new DecimalFormat("0.00"); File imgFile = new File(filePath); double bytes = imgFile.length(); double kilobytes = (bytes / 1024); double megabytes = (kilobytes / 1024); AppConfig.makeLog(TAG, "image size in mb:" + df.format(megabytes), 0); double filesize = Double.parseDouble(df.format(megabytes)); if (filesize > 2.00f) { for (int i = 0; i < filesize; i = i + 2) { imageScal++; } int remind = imageScal / 2; if (remind != 0) { imageScal = imageScal + 1; } makeLog(TAG, "image scale:" + imageScal, 0); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeFile(filePath, options); int actualHeight = options.outHeight; int actualWidth = options.outWidth; float maxHeight = 4000; float maxWidth = 6000; // float imgRatio = actualWidth / actualHeight; // float maxRatio = maxWidth / maxHeight; if (actualHeight > maxHeight) { imageScal = imageScal + 4; } if (actualWidth > maxWidth) { imageScal = imageScal + 8; } // 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; // // } // } // options.inSampleSize = utils.calculateInSampleSize(options, actualWidth, actualHeight); options.inSampleSize = imageScal; options.inJustDecodeBounds = false; options.inDither = true; options.inPurgeable = true; options.inInputShareable = true; options.inTempStorage = new byte[16 * 1024]; try { bmp = BitmapFactory.decodeFile(filePath, options); bmp = decodeFile(filePath); } catch (OutOfMemoryError exception) { exception.printStackTrace(); } boolean done = false; while (!done) { try { scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888); // scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888); done = true; } catch (OutOfMemoryError exception) { // 15923 × 1790 // 5616 × 3744 // 8150 × 9154 actualWidth = actualWidth - ((actualWidth * 2) / 100); actualHeight = actualHeight - ((actualHeight * 2) / 100); // scaledBitmap = Bitmap.createBitmap(5616, 3744, Bitmap.Config.ARGB_8888); 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)); // Resize image stored in sdcard FileOutputStream out = null; // filename =AppConfig.fileTosaveMedia(context, FileType.IMAGE, true).getAbsolutePath(); int compress = 50; try { do { imgFile = AppConfig.fileTosaveMedia(context, FileType.IMAGE, true); out = new FileOutputStream(imgFile); scaledBitmap.compress(Bitmap.CompressFormat.JPEG, compress, out); resizeImagePath = imgFile.getAbsolutePath(); // Thread.sleep(15000); // imgFile = new File(filename); bytes = imgFile.length(); kilobytes = (bytes / 1024); megabytes = (kilobytes / 1024); System.out.println("resized image size in mb:" + df.format(megabytes)); filesize = Double.parseDouble(df.format(megabytes)); if (filesize > 2.00f) { compress = 30; } } while (filesize > 2.00f); scaledBitmap.recycle(); } catch (Exception e) { e.printStackTrace(); } } else { FileOutputStream out = null; // FileInputStream in = null; imgFile = AppConfig.fileTosaveMedia(context, FileType.IMAGE, true); resizeImagePath = imgFile.getAbsolutePath(); InputStream in = null; OutputStream outTemp = null; try { // create output directory if it doesn't exist in = new FileInputStream(filePath); outTemp = new FileOutputStream(resizeImagePath); byte[] buffer = new byte[1024]; int read; while ((read = in.read(buffer)) != -1) { outTemp.write(buffer, 0, read); } in.close(); in = null; // write the output file (You have now copied the file) outTemp.flush(); outTemp.close(); outTemp = null; } catch (FileNotFoundException fnfe1) { Log.e("tag", fnfe1.getMessage()); } catch (Exception e) { Log.e("tag", e.getMessage()); } // try // { // Bitmap bmp = decodeFile(filePath); // // in = new FileInputStream(new File(imagePath)); // // persistImage(bitmap, name); // out = new FileOutputStream(resizeImagePath); // bmp.compress(Bitmap.CompressFormat.JPEG, 100, out); // out.flush(); // out.close(); // // FileIO.copyStream(in, out); // } // catch (Exception e) // { // e.printStackTrace(); // } } CustomLogHandler.printDebug(TAG, "resizeImagePath:" + resizeImagePath); return resizeImagePath; } 

Pasé mucho tiempo en blogs de búsqueda y lectura de Google. Después de crear el código anterior, encontré esto .

¿Es correcto el código anterior? ¿O hay alguna otra biblioteca para usar para comprimir imágenes?

Por favor, ayúdame.

Intente abajo el código: –

 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; } 

Para obtener más información, consulte el siguiente enlace:

http://voidcanvas.com/whatsapp-like-image-compression-in-android/

Hope ayuda a esto

  public static String compressImage(String filePath) { Bitmap scaledBitmap = null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeFile(filePath, options); int actualHeight = options.outHeight; int actualWidth = options.outWidth; float maxHeight = 400.0f; float maxWidth = 300.0f; float imgRatio = actualWidth / actualHeight; float maxRatio = maxWidth / maxHeight; 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; } } 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; } public static String getFilename() { File file = new File(Environment.getExternalStorageDirectory().getPath(), "Foldername/Images"); if (!file.exists()) { file.mkdirs(); } String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg"); return uriSting; } public static 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; } public static Bitmap highlightImage(Bitmap src) { // create new bitmap, which will be painted and becomes result image Bitmap bmOut = Bitmap.createBitmap(src.getWidth() + 96, src.getHeight() + 96, Bitmap.Config.ARGB_8888); // setup canvas for painting Canvas canvas = new Canvas(bmOut); // setup default color canvas.drawColor(0, PorterDuff.Mode.CLEAR); // create a blur paint for capturing alpha Paint ptBlur = new Paint(); ptBlur.setMaskFilter(new BlurMaskFilter(15, Blur.NORMAL)); int[] offsetXY = new int[2]; // capture alpha into a bitmap Bitmap bmAlpha = src.extractAlpha(ptBlur, offsetXY); // create a color paint Paint ptAlphaColor = new Paint(); ptAlphaColor.setColor(0xFFFFFFFF); // paint color for captured alpha region (bitmap) canvas.drawBitmap(bmAlpha, offsetXY[0], offsetXY[1], ptAlphaColor); // free memory bmAlpha.recycle(); // paint the image source canvas.drawBitmap(src, 0, 0, null); // return out final image return bmOut; } 

Prueba este código

 private void previewCapturedImage() { try { int targetW = 450; int targetH = 450; Log.e("Get w", "width" + targetW); Log.e("Get H", "height" + targetH); // Get the dimensions of the bitmap BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(filename, bmOptions); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; // Determine how much to scale down the image int scaleFactor = Math.min(photoW / targetW, photoH / targetH); // Decode the image file into a Bitmap sized to fill the View bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor << 1; bmOptions.inPurgeable = true; Bitmap bitmap = BitmapFactory.decodeFile(filename, bmOptions); Matrix mtx = new Matrix(); try { File imageFile = new File(filename); imageFile1 = imageFile; ExifInterface exif = new ExifInterface( imageFile.getAbsolutePath()); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); Log.e("Orintation", " :-" + orientation); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_270: mtx.postRotate(270); rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mtx, true); if (rotatedBMP != bitmap) bitmap.recycle(); imgPreview.setImageBitmap(rotatedBMP); break; case ExifInterface.ORIENTATION_ROTATE_180: mtx.postRotate(180); rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mtx, true); if (rotatedBMP != bitmap) bitmap.recycle(); imgPreview.setImageBitmap(rotatedBMP); break; case ExifInterface.ORIENTATION_ROTATE_90: mtx.postRotate(90); rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mtx, true); if (rotatedBMP != bitmap) bitmap.recycle(); imgPreview.setImageBitmap(rotatedBMP); break; case ExifInterface.ORIENTATION_NORMAL: mtx.postRotate(0); rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mtx, true); if (rotatedBMP != bitmap) bitmap.recycle(); imgPreview.setImageBitmap(rotatedBMP); break; default: mtx.postRotate(0); rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mtx, true); if (rotatedBMP != bitmap) bitmap.recycle(); imgPreview.setImageBitmap(rotatedBMP); // img_profilepic.setImageBitmap(BitmapFactory // .decodeFile(mCurrentPhotoPath)); } double megabytes = 0; if (imageFile1.exists()) { double bytes = imageFile1.length(); double kilobytes = (bytes / 1024); megabytes = (kilobytes / 1024); double gigabytes = (megabytes / 1024); double terabytes = (gigabytes / 1024); double petabytes = (terabytes / 1024); double exabytes = (petabytes / 1024); double zettabytes = (exabytes / 1024); double yottabytes = (zettabytes / 1024); Log.e("Image Size After in KB", "20th May:" + kilobytes); Log.e("Image Size After in MB", "20th May:" + megabytes); } int AfterSize = rotatedBMP.getRowBytes() * rotatedBMP.getHeight(); Log.e("After Compress Withd ", "21st May ::" + rotatedBMP.getWidth()); Log.e("After Compress Withd ", "21st May ::" + rotatedBMP.getWidth()); Log.i("RotateImage", "Exif orientation: " + orientation); tv_After.setText("After Width:" + rotatedBMP.getWidth() + " :Height:" + rotatedBMP.getHeight() + ":in MB :" + megabytes + " :Bitmap: " + AfterSize); } catch (Exception e) { e.printStackTrace(); } } catch (NullPointerException e) { e.printStackTrace(); } } 

También poner este método.

 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++; } Log.e("In Sample Size..", "19th May :-" + inSampleSize); return inSampleSize; } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.