Image compression to achieve file size limit (Android)

I applied the code below to scale the image in relation to the aspect ratio (proportionally reducing the height / width relative to each other). This will certainly help reduce the size of the images uploaded to my backend, but this does not take into account the resolution of the images. I want to set a hard image limit of, say, 800 KB, and if the image is changed to more than 800 KB, then compress it to a point that is less than 800 KB.

Does anyone have something like this? I'm curious about the relationship between the quality argument passed to the Bitmap.Compress method and the file size shaved for percentage quality. If I could get this information, I believe that I can achieve my goal.

Thank you for any help in advance, my current code is below, perhaps this will help other leaders in this direction in the future.

public static void uploadImage(String url, File file, Callback callback, Context context,
                               IMAGE_PURPOSE purpose) {

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);

    int maxWidth = 0;
    int maxHeight = 0;
    int maxSize = 0;
    switch(purpose){
        case PROFILE:
            maxWidth = Constants.MAX_PROFILE_IMAGE_WIDTH;
            maxHeight = Constants.MAX_PROFILE_IMAGE_HEIGHT;
            maxSize = Constants.MAX_PROFILE_IMAGE_SIZE;
            break;
        case UPLOAD:
            maxWidth = Constants.MAX_UPLOAD_IMAGE_WIDTH;
            maxHeight = Constants.MAX_UPLOAD_IMAGE_HEIGHT;
            maxSize = Constants.MAX_UPLOAD_IMAGE_SIZE;
            break;
    }

    int newWidth = bitmap.getWidth();
    int newHeight = bitmap.getHeight();

    // Make sure the width is OK
    if(bitmap.getWidth() > maxWidth){

        // Find out how much the picture had to shrink to get to our max defined width
        float shrinkCoeff = ((float)(bitmap.getWidth() - maxWidth) / (float)bitmap.getWidth());
        newWidth = maxWidth;

        // Shrink the height by the same amount to maintain aspect ratio
        newHeight = bitmap.getHeight() - (int)((float)bitmap.getHeight() * shrinkCoeff);
    }

    // Make sure the height is OK
    if(newHeight > maxHeight){

        // Find out how much the picture had to shrink to get to our max defined width
        float shrinkCoeff = ((newHeight - maxHeight) / newHeight);
        newHeight = maxHeight;

        // Shrink the width by the same amount to maintain aspect ratio
        newWidth = newWidth - (int)((float)newWidth * shrinkCoeff);
    }

    Bitmap resized = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);

    // Get the image in bytes
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    resized.compress(Bitmap.CompressFormat.JPEG, 100, bos);
    byte[] imageBytes = bos.toByteArray();

    // If the size on disk is too big, reduce the quality
    if(imageBytes.length > maxSize){
        // Compress image here to get to maxSize
    }
+4
source share

Source: https://habr.com/ru/post/1661401/


All Articles