2

I'm getting from a server a image in a String variable, that I need to reduce in the mobile and reupload. I have the next functions but I don't know why it takes so much time, I really don't know if it is blocked/freezed on some point or it takes so much time for the process.

public static String encodeToBase64(Bitmap image, Bitmap.CompressFormat compressFormat, int quality)
    {
        ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
        image.compress(compressFormat, quality, byteArrayOS);
        return Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT);
    }

    public static Bitmap decodeBase64(String input)
    {
        byte[] decodedBytes = Base64.decode(input, Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
    }

    public static String compressImage(String base64ImageData){

        long SIZE_1_5_MB = 1572864;
        int QUALITY = 100;

        Bitmap decodedByte = decodeBase64(base64ImageData);

        StringBuilder sb = new StringBuilder();

        do{
            sb.setLength(0);
            sb = new StringBuilder();
            String eBase64 = encodeToBase64(decodedByte, Bitmap.CompressFormat.JPEG, QUALITY);
            sb.append(eBase64);
            Log.e("IMAGE", "QUALITY: " + QUALITY + " SIZE: " + sb.length());
            QUALITY = QUALITY - 5;
        }while (sb.length() > SIZE_1_5_MB);

        return sb.toString();

    }

I want to reduce the photos to a size less than 1,5 mb

Víctor Martín
  • 3,352
  • 7
  • 48
  • 94

2 Answers2

2

you can resize the image bitmap. it can use to reduce the size of image

public Bitmap getResizeBitmap(Bitmap bm, int newWidth, int newHeight) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // CREATE A MATRIX FOR THE MANIPULATION
        Matrix matrix = new Matrix();
        // RESIZE THE BIT MAP
        matrix.postScale(scaleWidth, scaleHeight);

        // "RECREATE" THE NEW BITMAP
        return Bitmap.createBitmap(
                bm, 0, 0, width, height, matrix, false);
    }

i hope this is help you

1

You have to change your implementation approach bit, here is my suggestion.

In your code base 64 encode and decode is happening every time in the loop it causes slowness. Instead, use base 64 decodes once when you read from the source and encode only once at end.

You can determine the approximate size of base 64 string by simple math calculation. becuase it will be 1.33 times bigger.

Here is your modified code looks like.

public static String compressImage(String base64ImageData){

    long SIZE_1_5_MB = 1572864;
    int QUALITY = 100;

    Bitmap bitmap = decodeBase64(base64ImageData);

    //        long currentImageLenghtIn100Percent = decodedByte.getByteCount()         / 12; //approxvalue, It vary based on device arch and image format
    //        { //Calculate actual size in 100 percent compressed format
    //            ByteArrayOutputStream stream = new ByteArrayOutputStream();
    //            decodedByte.compress(Bitmap.CompressFormat.JPEG, 100, stream);
    //            currentImageLenghtIn100Percent = stream.toByteArray().length;
    //        }
    //
    //        //If you are targed teh base 64 string to be limited to 1.5 mb then convert size to base 64
    //        currentImageLenghtIn100Percent =  (long) ((currentImageLenghtIn100Percent * 4.0)/3.0f);
    //
    //        //If possible try calculate the compress ratio, it will avoid the do while loop
    //        double compressRatio = ((double) currentImageLenghtIn100Percent)/((double) SIZE_1_5_MB);

    ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();

    do{
        bitmap.compress(Bitmap.CompressFormat.JPEG, QUALITY, byteArrayOS);

        Log.e("IMAGE", "QUALITY: " + QUALITY + " SIZE of Image: " + byteArrayOS.toByteArray().length + " ~Size of Base 64" + byteArrayOS.toByteArray().length * 4 /3);
        QUALITY = QUALITY - 5;
    }while ((byteArrayOS.toByteArray().length * 4 /3) > SIZE_1_5_MB); //~ base 64 is 1.33 times larger than actual size

    return Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT);

}
Bertram Gilfoyle
  • 9,899
  • 6
  • 42
  • 67
Sai Prasad
  • 286
  • 1
  • 2
  • 13