Skip to content

Instantly share code, notes, and snippets.

@vipulasri
Created December 19, 2015 06:01
Show Gist options
  • Save vipulasri/0cd97d012934531f1266 to your computer and use it in GitHub Desktop.
Save vipulasri/0cd97d012934531f1266 to your computer and use it in GitHub Desktop.
Whatsapp Like Image Compression
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.media.ExifInterface;
import android.os.AsyncTask;
import android.os.Environment;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by HP-HP on 03-07-2015.
*/
public class ImageCompression extends AsyncTask<String, Void, String> {
private Context context;
private static final float maxHeight = 1280.0f;
private static final float maxWidth = 1280.0f;
public ImageCompression(Context context){
this.context=context;
}
@Override
protected String doInBackground(String... strings) {
if(strings.length == 0 || strings[0] == null)
return null;
return compressImage(strings[0]);
}
protected void onPostExecute(String imagePath){
// imagePath is path of new compressed image.
}
public String compressImage(String imagePath) {
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
float imgRatio = (float) actualWidth / (float) 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.inDither = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
bmp = BitmapFactory.decodeFile(imagePath, options);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.RGB_565);
} 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));
if(bmp!=null)
{
bmp.recycle();
}
ExifInterface exif;
try {
exif = new ExifInterface(imagePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
Matrix matrix = new Matrix();
if (orientation == 6) {
matrix.postRotate(90);
} else if (orientation == 3) {
matrix.postRotate(180);
} else if (orientation == 8) {
matrix.postRotate(270);
}
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream out = null;
String filepath = getFilename();
try {
out = new FileOutputStream(filepath);
//write the compressed bitmap at the destination specified by filename.
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return filepath;
}
public static 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;
}
public String getFilename() {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ context.getApplicationContext().getPackageName()
+ "/Files/Compressed");
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
mediaStorageDir.mkdirs();
}
String mImageName="IMG_"+ String.valueOf(System.currentTimeMillis()) +".jpg";
String uriString = (mediaStorageDir.getAbsolutePath() + "/"+ mImageName);;
return uriString;
}
}
@j2mistry
Copy link

scaledBitmap!!.compress(Bitmap.CompressFormat.JPEG, 80, out)
make above code 100% to achieve similar quality.
Refer RGB manpulation algo, to increase the quality of code

@RakeshPatil111
Copy link

RakeshPatil111 commented Jan 21, 2020 via email

@gropaul
Copy link

gropaul commented Apr 29, 2020

That´s awesome, great work!

@developervineetjoshi
Copy link

sir i passed the image path directly to the class by writing :

new ImageCompression(context).execute("content://com.android.providers.media.documents/document/image%3A20702");

but its showing error

can you please help me out with this

@prashantDahat1234
Copy link

prashantDahat1234 commented Jun 16, 2020

Caused by: java.lang.IllegalArgumentException: width and height must be > 0. in "scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.RGB_565) "
please help me...

@ajinkya5130
Copy link

Work like Pro...Thank you.

@Prabha10cs
Copy link

inPurgeable and inInputShareable deprecated

any solution

@ABHINAVABHISHEK
Copy link

I am getting error java.lang.IllegalArgumentException: width and height must be > 0

@ravikant2712
Copy link

I am getting error java.lang.IllegalArgumentException: width and height must be > 0

SAME HERE

@AbdullahJaved-dev
Copy link

I am getting error java.lang.IllegalArgumentException: width and height must be > 0

pass actual path of image instead of content Uri to avoid this exception.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment