KJEjava48 KJEjava48 - 8 months ago 35
Android Question

Android : How to reduce the size of the selected file

In our android application we need to upload files from galary and camera and which may be of any size depending on te phone, the size may be more than 2mb in some devices, so i need to reduce the size to below 100kb so it will be easy to keep in database and can fix the OutOfMemory error.Which is the best method to reduce the size of file ? I saw in watsapp when we upload an image of more than 6mb it will be reduced to approximately 50kb.How did that happen.Is it by finding the best inSampleSize and then decoding the file using that?

Answer Source

Compress file size using this class

public class CompressImage {

Context mContext;

public CompressImage(Context context) {
    this.mContext = context;
}

public String compressImage(String imageUri) throws IOException {

    String filePath = getRealPathFromURI(imageUri);
    if (filePath == null) {
        filePath = imageUri;
    }
    Bitmap scaledBitmap = null;

    BitmapFactory.Options options = new BitmapFactory.Options();

    options.inJustDecodeBounds = true;
    Bitmap bmp = BitmapFactory.decodeFile(filePath, options);

    int actualHeight = options.outHeight;
    int actualWidth = options.outWidth;


    float maxHeight = 816.0f;
    float maxWidth = 612.0f;
    float imgRatio = actualWidth / actualHeight;
    float maxRatio = maxWidth / maxHeight;


    if (actualHeight > maxHeight || actualWidth > maxWidth) {
        if (imgRatio < maxRatio) {
            imgRatio = maxHeight / actualHeight;
            actualWidth = (int) (imgRatio * actualWidth);
            actualHeight = (int) maxHeight;
        } else if (imgRatio > maxRatio) {
            imgRatio = maxWidth / actualWidth;
            actualHeight = (int) (imgRatio * actualHeight);
            actualWidth = (int) maxWidth;
        } else {
            actualHeight = (int) maxHeight;
            actualWidth = (int) maxWidth;

        }
    }


    options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);

    options.inJustDecodeBounds = false;

    options.inPurgeable = true;
    options.inInputShareable = true;
    options.inTempStorage = new byte[16 * 1024];

    try {
        bmp = BitmapFactory.decodeFile(filePath, options);
    } catch (OutOfMemoryError exception) {
        exception.printStackTrace();

    }
    try {
        scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
    } catch (OutOfMemoryError exception) {
        exception.printStackTrace();
    }

    float ratioX = actualWidth / (float) options.outWidth;
    float ratioY = actualHeight / (float) options.outHeight;
    float middleX = actualWidth / 2.0f;
    float middleY = actualHeight / 2.0f;

    Matrix scaleMatrix = new Matrix();
    scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

    Canvas canvas = new Canvas(scaledBitmap);
    canvas.setMatrix(scaleMatrix);
    canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));

    ExifInterface exif;
    try {
        exif = new ExifInterface(filePath);

        int orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION, 0);
        Log.d("EXIF", "Exif: " + orientation);
        Matrix matrix = new Matrix();
        if (orientation == 6) {
            matrix.postRotate(90);
            Log.d("EXIF", "Exif: " + orientation);
        } else if (orientation == 3) {
            matrix.postRotate(180);
            Log.d("EXIF", "Exif: " + orientation);
        } else if (orientation == 8) {
            matrix.postRotate(270);
            Log.d("EXIF", "Exif: " + orientation);
        }
        scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
                true);
    } catch (IOException e) {
        e.printStackTrace();
    }

    FileOutputStream out = null;
    String filename = imageUri;
    File oldfile = new File(imageUri);
    if (oldfile.exists()) {
        oldfile.delete();
    }
    try {
        out = new FileOutputStream(filename);

        scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    return filename;

}

public String getFilename() throws IOException {

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
            .format(new Date());
    String imageFileName = "twice_" + timeStamp + "_";
    File storageDir = Environment
            .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(imageFileName, /* prefix */
            ".jpg", /* suffix */
            storageDir /* directory */
    );

    return image.getAbsolutePath();

}

private String getRealPathFromURI(String contentURI) {
    Uri contentUri = Uri.parse(contentURI);
    Cursor cursor = mContext.getContentResolver().query(contentUri, null, null, null, null);
    if (cursor == null) {
        return contentUri.getPath();
    } else {
        cursor.moveToFirst();
        int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        return cursor.getString(index);
    }
}

public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
    final float totalPixels = width * height;
    final float totalReqPixelsCap = reqWidth * reqHeight * 2;
    while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
        inSampleSize++;
    }

    return inSampleSize;
}

}