Image compression like Whatsapp and other messengers on Android

杀马特。学长 韩版系。学妹 提交于 2019-11-28 05:03:57

Try below code :-

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;

    }

for for information see below link :-

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

saeed

Hope Helps this

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

Try this code

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

also put this method.

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

I have used the Top answer... The mentioned method is not working, it returning empty path in some Xiaomi phones because there is some problem with getting file path from Uri. use the getFilePath() instead of getRealPathFromURI()... and change parameters from compressImage(String imageUri) to compressImage(Uri imageUri).

private static String getFilePath(Context context, Uri uri) {
    String selection = null;
    String[] selectionArgs = null;
    // Uri is different in versions after KITKAT (Android 4.4), we need to
    if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            return Environment.getExternalStorageDirectory() + "/" + split[1];
        } else if (isDownloadsDocument(uri)) {
            final String id = DocumentsContract.getDocumentId(uri);
            uri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
        } else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];
            if ("image".equals(type)) {
                uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }
            selection = "_id=?";
            selectionArgs = new String[]{
                    split[1]
            };
        }
    }
    if ("content".equalsIgnoreCase(uri.getScheme())) {
        String[] projection = {
                MediaStore.Images.Media.DATA
        };
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver()
                    .query(uri, projection, selection, selectionArgs, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            if (cursor.moveToFirst()) {
                return cursor.getString(column_index);
            }
        } catch (Exception e) {
        }
    } else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }
    return null;
}

private static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

private static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

private static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!