0

When the user selects an image from the gallery, I convert it into a base64 string. Then I use an API. The image size must be less than 2MB, so if the image from the gallery is bigger than 2MB, I need to reduce its size. How should I do that?

That's my code:

// I pass the URI of the image to the method
@Override
    protected Integer doInBackground(Uri... uris) {

        InputStream inputStream = null;
        try {
            inputStream = getContentResolver().openInputStream(uris[0]);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        byte[] buffer = new byte[8192];
        int bytesRead;
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                output.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        bytes = output.toByteArray();
        String encodedImage = Base64.encodeToString(bytes, Base64.NO_WRAP);
Alireza Noorali
  • 3,129
  • 2
  • 33
  • 80
Nicola
  • 301
  • 3
  • 20

2 Answers2

0

You can create a Bitmap object using

BitmapFactory.decodeByteArray

Decode an immutable bitmap from the specified byte array.

and then you can use

bitmap.compress

Write a compressed version of the bitmap to the specified outputstream. If this returns true, the bitmap can be reconstructed by passing a corresponding inputstream to BitmapFactory.decodeStream(). Note: not all Formats support all bitmap configs directly, so it is possible that the returned bitmap from BitmapFactory could be in a different bitdepth, and/or may have lost per-pixel alpha (e.g. JPEG only supports opaque pixels).

This method may take several seconds to complete, so it should only be called from a worker thread.

and/or

Bitmap.createScaledBitmap

Creates a new bitmap, scaled from an existing bitmap, when possible. If the specified width and height are the same as the current width and height of the source bitmap, the source bitmap is returned and no new bitmap is created.

In my project I created two utility functions that might help you understand how to use the functions I mentioned above to fit your needs

public static Bitmap base64ToBitmap(String encodedImage) {
    byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
    return BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
}

public static String bitmapToBase64(Bitmap bitmap, int quality, int percentScale) {
    if (quality < 0 || quality > 100) {
        quality = IMAGE_QUALITY_DEFAULT_VALUE;
    }
    if (percentScale < 0 || percentScale > 100) {
        percentScale = IMAGE_SCALE_DEFAULT_VALUE;
    }

    float scale = (float) percentScale / 100;
    int width = Math.round(bitmap.getWidth() * scale);
    int height = Math.round(bitmap.getHeight() * scale);
    bitmap = Bitmap.createScaledBitmap(bitmap, width, height, true);

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, byteArrayOutputStream);
    byte[] byteArray = byteArrayOutputStream.toByteArray();
    return Base64.encodeToString(byteArray, Base64.NO_WRAP);
}
Dimitris Maragkos
  • 8,932
  • 2
  • 8
  • 26
0

One way to easily check the image and store it is according to the developer docs https://developer.android.com/topic/performance/graphics/load-bitmap#java Which gives a solution to your answer explained properly and another way is to change the size of the image which can be found here and then use it accordingly https://developer.android.com/reference/android/graphics/drawable/ScaleDrawable

Mohd Akbar
  • 111
  • 5