Search code examples
androidbitmapbase64image-resizing

How to avoid image from distort in Android?


I want to reuse size of bitmap when I send to server as base64. For example, original image size is 1.2 MB so I have to resize it to 50KB (server limit side). The way make image distort sometimes. I have read [1] and [2], but it didn't help.

The problem is some image become distort after resize.

Here is my code:

private String RescaleImage(String bitmap, int size) {
    try {
        if ((float) bitmap.getBytes().length / 1000 <= Constants.PROFILE_IMAGE_LIMITED_SIZE) {
            return bitmap;
        } else {
            //Rescale
            Log.d("msg", "rescale size : " + size);
            size -= 1;
            bitmap = BitmapBase64Util.encodeToBase64(Bitmap.createScaledBitmap(decodeBase64(bitmap), size, size, false));
            return RescaleImage(bitmap, size);
        }
    } catch (Exception e) {
        return bitmap;
    }
}

encodingToBase64:

public static String encodeToBase64(Bitmap image) {
    Log.d(TAG, "encoding image");

    String result = "";
    if (image != null) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] b = baos.toByteArray();
        result = Base64.encodeToString(b, Base64.DEFAULT);

        Log.d(TAG, result);
        return result;
    }
    return result;
}

Image is cropped before resize. Size after cropped is 300 x 300

My question is:

How to reuse image size to 50KB, keep same ratio and avoid distort?


Solution

  • I update my code and it work better now.

    -- FixED --

    Instead of resize the bitmap string continuously, I use the orignal bitmap that is used before resize.

    private String RescaleImage(String bitmap, Bitmap origin_bitmap, int size) {
        try {
            if ((float) bitmap.getBytes().length / 1000 <= Constants.PROFILE_IMAGE_LIMITED_SIZE) {
                return bitmap;
            } else {
                //Rescale
                Log.d("msg", "rescale size : " + size);
                size -= 1;
                bitmap = BitmapBase64Util.encodeToBase64(Bitmap.createScaledBitmap(origin_bitmap, size, size, false));
                return RescaleImage(bitmap, origin_bitmap, size);
            }
        } catch (Exception e) {
            return bitmap;
        }
    }
    

    Also, use this code when decode to reuse distortion. Bad image quality after resizing/scaling bitmap.

    If there are better fix, I always welcome in order to improve.