Android reduce el tamaño del archivo para que la imagen capturada de la cámara sea inferior a 500 kb

Mi requisito es cargar la imagen capturada de la cámara al servidor, pero debe ser inferior a 500 KB. En caso de que sea superior a 500 KB, debe reducirse al tamaño inferior a 500 KB.(pero algo más cerca de eso)

Para esto, estoy usando el siguiente código:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        try {
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == getActivity().RESULT_OK) {

                    if (requestCode == REQUEST_CODE_CAMERA) {

                        try {

                            photo = MediaStore.Images.Media.getBitmap(
                                    ctx.getContentResolver(), capturedImageUri);
                            String selectedImagePath = getRealPathFromURI(capturedImageUri);

                            img_file = new File(selectedImagePath);

                            Log.d("img_file_size", "file size in KBs (initially): " + (img_file.length()/1000));

                            if(CommonUtilities.isImageFileSizeGreaterThan500KB(img_file)) {
                                photo = CommonUtilities.getResizedBitmapLessThan500KB(photo, 500);
                            }
                            photo = CommonUtilities.getCorrectBitmap(photo, selectedImagePath);


//  // CALL THIS METHOD TO GET THE URI FROM THE BITMAP

                            img_file = new File(ctx.getCacheDir(), "image.jpg");
                            img_file.createNewFile();

//Convert bitmap to byte array
                            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                            photo.compress(Bitmap.CompressFormat.JPEG, 100, bytes);

//write the bytes in file
                            FileOutputStream fo = new FileOutputStream(img_file);
                            fo.write(bytes.toByteArray());

// remember close de FileOutput
                            fo.close();
                            Log.d("img_file_size", "file size in KBs after image manipulations: " + (img_file.length()/1000));


                        } catch (Exception e) {
                            Logs.setLogException(class_name, "onActivityResult(), when captured from camera", e);
                        }


                    } 

            }
        } catch (Exception e) {
            Logs.setLogException(class_name, "onActivityResult()", e);
        } catch (OutOfMemoryError e) {
            Logs.setLogError(class_name, "onActivityResult()", e);

        }
    }

Y

public static Bitmap getResizedBitmapLessThan500KB(Bitmap image, int maxSize) {
        int width = image.getWidth();
        int height = image.getHeight();



        float bitmapRatio = (float)width / (float) height;
        if (bitmapRatio > 0) {
            width = maxSize;
            height = (int) (width / bitmapRatio);
        } else {
            height = maxSize;
            width = (int) (height * bitmapRatio);
        }
        Bitmap reduced_bitmap = Bitmap.createScaledBitmap(image, width, height, true);
        if(sizeOf(reduced_bitmap) > (500 * 1000)) {
            return getResizedBitmap(reduced_bitmap, maxSize);
        } else {
            return reduced_bitmap;
        }
    }

Para rotar la imagen, si es necesario.

public static Bitmap getCorrectBitmap(Bitmap bitmap, String filePath) {
        ExifInterface ei;
        Bitmap rotatedBitmap = bitmap;
        try {
            ei = new ExifInterface(filePath);

            int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            Matrix matrix = new Matrix();
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    matrix.postRotate(90);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    matrix.postRotate(180);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    matrix.postRotate(270);
                    break;
            }

            rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return rotatedBitmap;
    }

Aquí está la salida del tamaño del archivo de imagen inicialmente y después de todas las operaciones para reducir el tamaño del archivo.

img_file_size ﹕ tamaño del archivo en KB (inicialmente): 3294

img_file_size size tamaño de archivo en KB después de manipulaciones de imagen: 235

Vea la diferencia anterior (en la salida). El tamaño de archivo inicial sin esas operaciones, y después de esas compresiones y otras operaciones. Necesito ese tamaño para estar algo más cerca de 500 kb.

El código anterior funciona bastante bien para mí, ya que reduce el tamaño del archivo de imagen para que sea inferior a 500 KB.

Pero, los siguientes son los problemas con el código anterior -

Este código está reduciendo el tamaño del archivo incluso si es inferior a 500 KB

En caso de que sea más de 500 KB, el tamaño de archivo reducido se vuelve demasiado menor de 500 KB, aunque lo necesito un poco más cerca.

Necesito deshacerme de los 2 problemas anteriores. Entonces, necesito saber qué debo manipular en el código anterior.

Como también quiero corregir la orientación EXIF (imágenes rotadas), junto con mi requisito mencionado anteriormente.

Respuestas a la pregunta(8)

Su respuesta a la pregunta