How to reduce an Image file size before uploading to a server How to reduce an Image file size before uploading to a server android android

How to reduce an Image file size before uploading to a server


I use this function to reduce the size of image before uploading it, it reduces the image size to nearly 200 KB and keep the quality relatively good, u may modify it to fulfill your purpose by changing the REQUIRED_SIZE and inSampleSize:

public File saveBitmapToFile(File file){    try {        // BitmapFactory options to downsize the image        BitmapFactory.Options o = new BitmapFactory.Options();        o.inJustDecodeBounds = true;        o.inSampleSize = 6;        // factor of downsizing the image        FileInputStream inputStream = new FileInputStream(file);        //Bitmap selectedBitmap = null;        BitmapFactory.decodeStream(inputStream, null, o);        inputStream.close();        // The new size we want to scale to        final int REQUIRED_SIZE=75;        // Find the correct scale value. It should be the power of 2.        int scale = 1;        while(o.outWidth / scale / 2 >= REQUIRED_SIZE &&                        o.outHeight / scale / 2 >= REQUIRED_SIZE) {            scale *= 2;        }        BitmapFactory.Options o2 = new BitmapFactory.Options();        o2.inSampleSize = scale;        inputStream = new FileInputStream(file);        Bitmap selectedBitmap = BitmapFactory.decodeStream(inputStream, null, o2);        inputStream.close();        // here i override the original image file        file.createNewFile();        FileOutputStream outputStream = new FileOutputStream(file);        selectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100 , outputStream);        return file;    } catch (Exception e) {        return null;    }}

NOTE: I resize and override the original file image in this function, u may write it to another file as well.

I hope it may help you.


This is working great Try this

private String decodeFile(String path,int DESIREDWIDTH, int DESIREDHEIGHT) {        String strMyImagePath = null;        Bitmap scaledBitmap = null;        try {            // Part 1: Decode image            Bitmap unscaledBitmap = ScalingUtilities.decodeFile(path, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);            if (!(unscaledBitmap.getWidth() <= DESIREDWIDTH && unscaledBitmap.getHeight() <= DESIREDHEIGHT)) {                // Part 2: Scale image                scaledBitmap = ScalingUtilities.createScaledBitmap(unscaledBitmap, DESIREDWIDTH, DESIREDHEIGHT, ScalingLogic.FIT);            } else {                unscaledBitmap.recycle();                return path;            }            // Store to tmp file            String extr = Environment.getExternalStorageDirectory().toString();            File mFolder = new File(extr + "/TMMFOLDER");            if (!mFolder.exists()) {                mFolder.mkdir();            }            String s = "tmp.png";            File f = new File(mFolder.getAbsolutePath(), s);            strMyImagePath = f.getAbsolutePath();            FileOutputStream fos = null;            try {                fos = new FileOutputStream(f);                scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 75, fos);                fos.flush();                fos.close();            } catch (FileNotFoundException e) {                e.printStackTrace();            } catch (Exception e) {                e.printStackTrace();            }            scaledBitmap.recycle();        } catch (Throwable e) {        }        if (strMyImagePath == null) {            return path;        }        return strMyImagePath;    }

ScalingUtilities.java

import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.graphics.BitmapFactory.Options;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;/** * Class containing static utility methods for bitmap decoding and scaling * * @author  */public class ScalingUtilities {    /**     * Utility function for decoding an image resource. The decoded bitmap will     * be optimized for further scaling to the requested destination dimensions     * and scaling logic.     *     * @param res The resources object containing the image data     * @param resId The resource id of the image data     * @param dstWidth Width of destination area     * @param dstHeight Height of destination area     * @param scalingLogic Logic to use to avoid image stretching     * @return Decoded bitmap     */    public static Bitmap decodeResource(Resources res, int resId, int dstWidth, int dstHeight,            ScalingLogic scalingLogic) {        Options options = new Options();        options.inJustDecodeBounds = true;        BitmapFactory.decodeResource(res, resId, options);        options.inJustDecodeBounds = false;        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,                dstHeight, scalingLogic);        Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);        return unscaledBitmap;    }    public static Bitmap decodeFile(String path, int dstWidth, int dstHeight,            ScalingLogic scalingLogic) {        Options options = new Options();        options.inJustDecodeBounds = true;        BitmapFactory.decodeFile(path, options);        options.inJustDecodeBounds = false;        options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth,                dstHeight, scalingLogic);        Bitmap unscaledBitmap = BitmapFactory.decodeFile(path, options);        return unscaledBitmap;    }    /**     * Utility function for creating a scaled version of an existing bitmap     *     * @param unscaledBitmap Bitmap to scale     * @param dstWidth Wanted width of destination bitmap     * @param dstHeight Wanted height of destination bitmap     * @param scalingLogic Logic to use to avoid image stretching     * @return New scaled bitmap object     */    public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,            ScalingLogic scalingLogic) {        Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),                dstWidth, dstHeight, scalingLogic);        Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),                dstWidth, dstHeight, scalingLogic);        Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),                Config.ARGB_8888);        Canvas canvas = new Canvas(scaledBitmap);        canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));        return scaledBitmap;    }    /**     * ScalingLogic defines how scaling should be carried out if source and     * destination image has different aspect ratio.     *     * CROP: Scales the image the minimum amount while making sure that at least     * one of the two dimensions fit inside the requested destination area.     * Parts of the source image will be cropped to realize this.     *     * FIT: Scales the image the minimum amount while making sure both     * dimensions fit inside the requested destination area. The resulting     * destination dimensions might be adjusted to a smaller size than     * requested.     */    public static enum ScalingLogic {        CROP, FIT    }    /**     * Calculate optimal down-sampling factor given the dimensions of a source     * image, the dimensions of a destination area and a scaling logic.     *     * @param srcWidth Width of source image     * @param srcHeight Height of source image     * @param dstWidth Width of destination area     * @param dstHeight Height of destination area     * @param scalingLogic Logic to use to avoid image stretching     * @return Optimal down scaling sample size for decoding     */    public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight,            ScalingLogic scalingLogic) {        if (scalingLogic == ScalingLogic.FIT) {            final float srcAspect = (float)srcWidth / (float)srcHeight;            final float dstAspect = (float)dstWidth / (float)dstHeight;            if (srcAspect > dstAspect) {                return srcWidth / dstWidth;            } else {                return srcHeight / dstHeight;            }        } else {            final float srcAspect = (float)srcWidth / (float)srcHeight;            final float dstAspect = (float)dstWidth / (float)dstHeight;            if (srcAspect > dstAspect) {                return srcHeight / dstHeight;            } else {                return srcWidth / dstWidth;            }        }    }    /**     * Calculates source rectangle for scaling bitmap     *     * @param srcWidth Width of source image     * @param srcHeight Height of source image     * @param dstWidth Width of destination area     * @param dstHeight Height of destination area     * @param scalingLogic Logic to use to avoid image stretching     * @return Optimal source rectangle     */    public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,            ScalingLogic scalingLogic) {        if (scalingLogic == ScalingLogic.CROP) {            final float srcAspect = (float)srcWidth / (float)srcHeight;            final float dstAspect = (float)dstWidth / (float)dstHeight;            if (srcAspect > dstAspect) {                final int srcRectWidth = (int)(srcHeight * dstAspect);                final int srcRectLeft = (srcWidth - srcRectWidth) / 2;                return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);            } else {                final int srcRectHeight = (int)(srcWidth / dstAspect);                final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;                return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);            }        } else {            return new Rect(0, 0, srcWidth, srcHeight);        }    }    /**     * Calculates destination rectangle for scaling bitmap     *     * @param srcWidth Width of source image     * @param srcHeight Height of source image     * @param dstWidth Width of destination area     * @param dstHeight Height of destination area     * @param scalingLogic Logic to use to avoid image stretching     * @return Optimal destination rectangle     */    public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,            ScalingLogic scalingLogic) {        if (scalingLogic == ScalingLogic.FIT) {            final float srcAspect = (float)srcWidth / (float)srcHeight;            final float dstAspect = (float)dstWidth / (float)dstHeight;            if (srcAspect > dstAspect) {                return new Rect(0, 0, dstWidth, (int)(dstWidth / srcAspect));            } else {                return new Rect(0, 0, (int)(dstHeight * srcAspect), dstHeight);            }        } else {            return new Rect(0, 0, dstWidth, dstHeight);        }    }}


Here's a solution that's handled in memory and doesn't require actually generating a file on the file system.

From some Fragment, after user selects an image file:

@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {    super.onActivityResult(requestCode, resultCode, imageReturnedIntent);    if (imageReturnedIntent == null            || imageReturnedIntent.getData() == null) {        return;    }    // aiming for ~500kb max. assumes typical device image size is around 2megs    int scaleDivider = 4;     try {        // 1. Convert uri to bitmap        Uri imageUri = imageReturnedIntent.getData();        Bitmap fullBitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), imageUri);        // 2. Get the downsized image content as a byte[]        int scaleWidth = fullBitmap.getWidth() / scaleDivider;        int scaleHeight = fullBitmap.getHeight() / scaleDivider;        byte[] downsizedImageBytes =                getDownsizedImageBytes(fullBitmap, scaleWidth, scaleHeight);        // 3. Upload the byte[]; Eg, if you are using Firebase        StorageReference storageReference =                FirebaseStorage.getInstance().getReference("/somepath");        storageReference.putBytes(downsizedImageBytes);    }    catch (IOException ioEx) {        ioEx.printStackTrace();    }}public byte[] getDownsizedImageBytes(Bitmap fullBitmap, int scaleWidth, int scaleHeight) throws IOException {    Bitmap scaledBitmap = Bitmap.createScaledBitmap(fullBitmap, scaleWidth, scaleHeight, true);    // 2. Instantiate the downsized image content as a byte[]    ByteArrayOutputStream baos = new ByteArrayOutputStream();    scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);    byte[] downsizedImageBytes = baos.toByteArray();    return downsizedImageBytes;}

Thanks to: