-1

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?

Cœur
  • 32,421
  • 21
  • 173
  • 232
K.Sopheak
  • 22,440
  • 4
  • 26
  • 73

2 Answers2

0

You pass the the same width and height in Bitmap.createScaledBitmap(decodeBase64(bitmap), size, size, false). Unless your bitmaps are squares you have to specify the right widht and height, otherwise your image gets distorted based on the original aspect ratio. I think something like this would work:

Bitmap scaledBitmap = Bitmap.createScaledBitmap(decodeBase64(bitmap);
bitmap = BitmapBase64Util.encodeToBase64(scaledBitmap, scaledBitmap.getWidth(), size.getHeight(), false);

If you need compression to reduce the size use this [Edit: You have done this]:

ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); 
byte[] byteArray = stream.toByteArray();
Endre Börcsök
  • 437
  • 1
  • 8
  • 19
  • Agree this idea. But how to make its size lower or equal 50KB? – K.Sopheak Jun 22 '17 at 09:51
  • 1
    With Bitmaps you can't. the bigger the resolution the bigger the size. If you have to compress your image use this `ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); byte[] byteArray = stream.toByteArray();` – Endre Börcsök Jun 22 '17 at 09:55
  • Actually, I compressed it already when encoded. See my update. – K.Sopheak Jun 22 '17 at 10:00
  • I see, the problem might come from `decodeBase64(bitmap)` or using the `size` as width and height. – Endre Börcsök Jun 22 '17 at 10:05
  • 1
    `RescaleImage(bitmap, size);` looks dodgy too. I would expect `RescaleImage(bitmap, width, height);` there too. What happens if you apply your logic to a square bitmap (100*100 or similar)? Does that get distorted? – Endre Börcsök Jun 22 '17 at 10:07
  • Image is cropped before resize. After crop, image size is 300 x 300. – K.Sopheak Jun 22 '17 at 10:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/147353/discussion-between-k-sopheak-and-endre-borcsok). – K.Sopheak Jun 22 '17 at 10:21
0

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.

K.Sopheak
  • 22,440
  • 4
  • 26
  • 73