Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reduce image size into 1MB

I want my application to upload image with no size limit, but in the code, I want to resize the image into 1MB if the image size exceeds. I have tried many ways but I couldn't find any code for the requirement I have mentioned above.

For once, I have tried this:

public void scaleDown() {
    int width = stdImageBmp.getWidth();
    int height = stdImageBmp.getHeight();
    Matrix matrix = new Matrix();
    float scaleWidth = ((float) MAX_WIDTH) / width;
    float scaleHeight = ((float) MAX_HEIGHT) / height;


    matrix.postScale(scaleWidth, scaleHeight);
    stdImageBmp = Bitmap.createBitmap(stdImageBmp, 0, 0, width, height, matrix, true);

    File Image = new File("path");


    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    //compress bmp
    stdImageBmp.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
    byte[] byteArray = byteArrayOutputStream.toByteArray();


    imgViewStd.setImageBitmap(stdImageBmp);
    Log.d("resizedBitmap", stdImageBmp.toString());

    width = stdImageBmp.getWidth();
    height = stdImageBmp.getHeight();
    System.out.println("imgWidth" + width);
    System.out.println("imgHeight" + height);
}
like image 648
Aysha Ashraf Avatar asked Jun 17 '16 04:06

Aysha Ashraf


2 Answers

you can use this code to resize a bitmap and for image size < 1MB i recommend use resolution of 480x640

public Bitmap getResizedBitmap(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);
    }
like image 164
M.Waqas Pervez Avatar answered Sep 28 '22 06:09

M.Waqas Pervez


If you really want the Bitmap that scales down to the Bitmap that is the closest to a given amount of bytes, heres the method I use. (It does not uses a while loop)

NOTE: This method only works if passed bitmap is in ARGB_8888 configuration. See: Compress bitmap to a specific byte size in Android for the conversion method.

/**
 * Method to scale the Bitmap to respect the max bytes
 *
 * @param input    the Bitmap to scale if too large
 * @param maxBytes the amount of bytes the Image may be
 * @return The scaled bitmap or the input if already valid
 * @Note: The caller of this function is responsible for recycling once the input is no longer needed
 */
public static Bitmap scaleBitmap(final Bitmap input, final long maxBytes) {
    final int currentWidth = input.getWidth();
    final int currentHeight = input.getHeight();
    final int currentPixels = currentWidth * currentHeight;
    // Get the amount of max pixels:
    // 1 pixel = 4 bytes (R, G, B, A)
    final long maxPixels = maxBytes / 4; // Floored
    if (currentPixels <= maxPixels) {
        // Already correct size:
        return input;
    }
    // Scaling factor when maintaining aspect ratio is the square root since x and y have a relation:
    final double scaleFactor = Math.sqrt(maxPixels / (double) currentPixels);
    final int newWidthPx = (int) Math.floor(currentWidth * scaleFactor);
    final int newHeightPx = (int) Math.floor(currentHeight * scaleFactor);
    Timber.i("Scaled bitmap sizes are %1$s x %2$s when original sizes are %3$s x %4$s and currentPixels %5$s and maxPixels %6$s and scaled total pixels are: %7$s",
            newWidthPx, newHeightPx, currentWidth, currentHeight, currentPixels, maxPixels, (newWidthPx * newHeightPx));
    final Bitmap output = Bitmap.createScaledBitmap(input, newWidthPx, newHeightPx, true);
    return output;
}

Where the Sample use would look something like:

// (1 MB)
final long maxBytes = 1024 * 1024; 
// Scale it
final Bitmap scaledBitmap = BitmapUtils.scaleBitmap(yourBitmap, maxBytes);
if(scaledBitmap != yourBitmap){
    // Recycle the bitmap since we can use the scaled variant:
    yourBitmap.recycle();
} 
// ... do something with the scaled bitmap

like image 44
Koen Avatar answered Sep 28 '22 06:09

Koen