I am using the following code for image compression.
The code compresses image files that are larger than 2 MB.
But this code takes time and image quality stays pure.
public static String compressImage(String imagePath, Context context)
{
String resizeImagePath = null;
String filePath = imagePath;
CustomLogHandler.printDebug(TAG, "resizeImagePath:" + imagePath);
Bitmap scaledBitmap = null;
int imageScal = 1;
// File size greater then 2mb
DecimalFormat df = new DecimalFormat("0.00");
File imgFile = new File(filePath);
double bytes = imgFile.length();
double kilobytes = (bytes / 1024);
double megabytes = (kilobytes / 1024);
AppConfig.makeLog(TAG, "image size in mb:" + df.format(megabytes), 0);
double filesize = Double.parseDouble(df.format(megabytes));
if (filesize > 2.00f)
{
for (int i = 0; i < filesize; i = i + 2)
{
imageScal++;
}
int remind = imageScal / 2;
if (remind != 0)
{
imageScal = imageScal + 1;
}
makeLog(TAG, "image scale:" + imageScal, 0);
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 = 4000;
float maxWidth = 6000;
// float imgRatio = actualWidth / actualHeight;
// float maxRatio = maxWidth / maxHeight;
if (actualHeight > maxHeight)
{
imageScal = imageScal + 4;
}
if (actualWidth > maxWidth)
{
imageScal = imageScal + 8;
}
// 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 = utils.calculateInSampleSize(options, actualWidth, actualHeight);
options.inSampleSize = imageScal;
options.inJustDecodeBounds = false;
options.inDither = true;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try
{
bmp = BitmapFactory.decodeFile(filePath, options);
bmp = decodeFile(filePath);
}
catch (OutOfMemoryError exception)
{
exception.printStackTrace();
}
boolean done = false;
while (!done)
{
try
{
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
// scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
done = true;
}
catch (OutOfMemoryError exception)
{
// 15923 × 1790
// 5616 × 3744
// 8150 × 9154
actualWidth = actualWidth - ((actualWidth * 2) / 100);
actualHeight = actualHeight - ((actualHeight * 2) / 100);
// scaledBitmap = Bitmap.createBitmap(5616, 3744, Bitmap.Config.ARGB_8888);
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));
// Resize image stored in sdcard
FileOutputStream out = null;
// filename =AppConfig.fileTosaveMedia(context, FileType.IMAGE, true).getAbsolutePath();
int compress = 50;
try
{
do
{
imgFile = AppConfig.fileTosaveMedia(context, FileType.IMAGE, true);
out = new FileOutputStream(imgFile);
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, compress, out);
resizeImagePath = imgFile.getAbsolutePath();
// Thread.sleep(15000);
// imgFile = new File(filename);
bytes = imgFile.length();
kilobytes = (bytes / 1024);
megabytes = (kilobytes / 1024);
System.out.println("resized image size in mb:" + df.format(megabytes));
filesize = Double.parseDouble(df.format(megabytes));
if (filesize > 2.00f)
{
compress = 30;
}
} while (filesize > 2.00f);
scaledBitmap.recycle();
}
catch (Exception e)
{
e.printStackTrace();
}
}
else
{
FileOutputStream out = null;
// FileInputStream in = null;
imgFile = AppConfig.fileTosaveMedia(context, FileType.IMAGE, true);
resizeImagePath = imgFile.getAbsolutePath();
InputStream in = null;
OutputStream outTemp = null;
try
{
// create output directory if it doesn't exist
in = new FileInputStream(filePath);
outTemp = new FileOutputStream(resizeImagePath);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
{
outTemp.write(buffer, 0, read);
}
in.close();
in = null;
// write the output file (You have now copied the file)
outTemp.flush();
outTemp.close();
outTemp = null;
}
catch (FileNotFoundException fnfe1)
{
Log.e("tag", fnfe1.getMessage());
}
catch (Exception e)
{
Log.e("tag", e.getMessage());
}
// try
// {
// Bitmap bmp = decodeFile(filePath);
// // in = new FileInputStream(new File(imagePath));
// // persistImage(bitmap, name);
// out = new FileOutputStream(resizeImagePath);
// bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
// out.flush();
// out.close();
// // FileIO.copyStream(in, out);
// }
// catch (Exception e)
// {
// e.printStackTrace();
// }
}
CustomLogHandler.printDebug(TAG, "resizeImagePath:" + resizeImagePath);
return resizeImagePath;
}
I spent so much time on Google search and reading blogs. Then after creating the above code, I found this.
Is the above code correct? Or is there any other library to use to compress images?
Please help me.
Hope Helps this
Try below code :-
for for information see below link :-
http://voidcanvas.com/whatsapp-like-image-compression-in-android/
Try this code
also put this method.
I have used the Top answer... The mentioned method is not working, it returning empty path in some Xiaomi phones because there is some problem with getting file path from Uri. use the getFilePath() instead of getRealPathFromURI()... and change parameters from compressImage(String imageUri) to compressImage(Uri imageUri).