我使用以下代码进行图像压缩。
代码压缩大于2 MB的图像文件。
但是这段代码需要时间和图像质量保持纯净。
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;
}
我在Google搜索和阅读博客上花了很多时间。然后在创建上述代码后,我找到了this。
以上代码是否正确?或者是否有其他库用于压缩图像?
请帮帮我。
答案 0 :(得分:24)
尝试以下代码: -
public String compressImage(String imageUri) {
String filePath = getRealPathFromURI(imageUri);
Bitmap scaledBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
// by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
// you try the use the bitmap here, you will get null.
options.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
// max Height and width values of the compressed image is taken as 816x612
float maxHeight = 816.0f;
float maxWidth = 612.0f;
float imgRatio = actualWidth / actualHeight;
float maxRatio = maxWidth / maxHeight;
// width and height values are set maintaining the aspect ratio of the image
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;
}
}
// setting inSampleSize value allows to load a scaled down version of the original image
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
// inJustDecodeBounds set to false to load the actual bitmap
options.inJustDecodeBounds = false;
// this options allow android to claim the bitmap memory if it runs low on memory
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
// load the bitmap from its path
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));
// check the rotation of the image and display it properly
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 = getFilename();
try {
out = new FileOutputStream(filename);
// write the compressed bitmap at the destination specified by filename.
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return filename;
}
有关信息,请参阅以下链接: -
http://voidcanvas.com/whatsapp-like-image-compression-in-android/
答案 1 :(得分:2)
希望帮助这个
public static String compressImage(String filePath) {
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 = 400.0f;
float maxWidth = 300.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);
// inJustDecodeBounds set to false to load the actual bitmap
options.inJustDecodeBounds = false;
// this options allow android to claim the bitmap memory if it runs low on memory
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
// load the bitmap from its path
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));
// check the rotation of the image and display it properly
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 = getFilename();
try {
out = new FileOutputStream(filename);
// write the compressed bitmap at the destination specified by filename.
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return filename;
}
public static String getFilename() {
File file = new File(Environment.getExternalStorageDirectory().getPath(), "Foldername/Images");
if (!file.exists()) {
file.mkdirs();
}
String uriSting = (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".jpg");
return uriSting;
}
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 static Bitmap highlightImage(Bitmap src) {
// create new bitmap, which will be painted and becomes result image
Bitmap bmOut = Bitmap.createBitmap(src.getWidth() + 96, src.getHeight() + 96, Bitmap.Config.ARGB_8888);
// setup canvas for painting
Canvas canvas = new Canvas(bmOut);
// setup default color
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
// create a blur paint for capturing alpha
Paint ptBlur = new Paint();
ptBlur.setMaskFilter(new BlurMaskFilter(15, Blur.NORMAL));
int[] offsetXY = new int[2];
// capture alpha into a bitmap
Bitmap bmAlpha = src.extractAlpha(ptBlur, offsetXY);
// create a color paint
Paint ptAlphaColor = new Paint();
ptAlphaColor.setColor(0xFFFFFFFF);
// paint color for captured alpha region (bitmap)
canvas.drawBitmap(bmAlpha, offsetXY[0], offsetXY[1], ptAlphaColor);
// free memory
bmAlpha.recycle();
// paint the image source
canvas.drawBitmap(src, 0, 0, null);
// return out final image
return bmOut;
}
答案 2 :(得分:1)
试试此代码
private void previewCapturedImage() {
try {
int targetW = 450;
int targetH = 450;
Log.e("Get w", "width" + targetW);
Log.e("Get H", "height" + targetH);
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor << 1;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(filename, bmOptions);
Matrix mtx = new Matrix();
try {
File imageFile = new File(filename);
imageFile1 = imageFile;
ExifInterface exif = new ExifInterface(
imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
Log.e("Orintation", " :-" + orientation);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
mtx.postRotate(270);
rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), mtx, true);
if (rotatedBMP != bitmap)
bitmap.recycle();
imgPreview.setImageBitmap(rotatedBMP);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
mtx.postRotate(180);
rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), mtx, true);
if (rotatedBMP != bitmap)
bitmap.recycle();
imgPreview.setImageBitmap(rotatedBMP);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
mtx.postRotate(90);
rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), mtx, true);
if (rotatedBMP != bitmap)
bitmap.recycle();
imgPreview.setImageBitmap(rotatedBMP);
break;
case ExifInterface.ORIENTATION_NORMAL:
mtx.postRotate(0);
rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), mtx, true);
if (rotatedBMP != bitmap)
bitmap.recycle();
imgPreview.setImageBitmap(rotatedBMP);
break;
default:
mtx.postRotate(0);
rotatedBMP = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), mtx, true);
if (rotatedBMP != bitmap)
bitmap.recycle();
imgPreview.setImageBitmap(rotatedBMP);
// img_profilepic.setImageBitmap(BitmapFactory
// .decodeFile(mCurrentPhotoPath));
}
double megabytes = 0;
if (imageFile1.exists()) {
double bytes = imageFile1.length();
double kilobytes = (bytes / 1024);
megabytes = (kilobytes / 1024);
double gigabytes = (megabytes / 1024);
double terabytes = (gigabytes / 1024);
double petabytes = (terabytes / 1024);
double exabytes = (petabytes / 1024);
double zettabytes = (exabytes / 1024);
double yottabytes = (zettabytes / 1024);
Log.e("Image Size After in KB", "20th May:" + kilobytes);
Log.e("Image Size After in MB", "20th May:" + megabytes);
}
int AfterSize = rotatedBMP.getRowBytes()
* rotatedBMP.getHeight();
Log.e("After Compress Withd ",
"21st May ::" + rotatedBMP.getWidth());
Log.e("After Compress Withd ",
"21st May ::" + rotatedBMP.getWidth());
Log.i("RotateImage", "Exif orientation: " + orientation);
tv_After.setText("After Width:" + rotatedBMP.getWidth()
+ " :Height:" + rotatedBMP.getHeight() + ":in MB :"
+ megabytes + " :Bitmap: " + AfterSize);
} catch (Exception e) {
e.printStackTrace();
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
也提出了这种方法。
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++;
}
Log.e("In Sample Size..", "19th May :-" + inSampleSize);
return inSampleSize;
}
答案 3 :(得分:0)
我用的是最高答案... 提到的方法不起作用,由于从Uri获取文件路径存在一些问题,它在某些小米手机中返回空路径。 使用 getFilePath()代替 getRealPathFromURI() ...,并将参数从 compressImage(String imageUri)更改为 compressImage(Uri imageUri)。
private static String getFilePath(Context context, Uri uri) {
String selection = null;
String[] selectionArgs = null;
// Uri is different in versions after KITKAT (Android 4.4), we need to
if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context.getApplicationContext(), uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
return Environment.getExternalStorageDirectory() + "/" + split[1];
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
uri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("image".equals(type)) {
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
selection = "_id=?";
selectionArgs = new String[]{
split[1]
};
}
}
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = {
MediaStore.Images.Media.DATA
};
Cursor cursor = null;
try {
cursor = context.getContentResolver()
.query(uri, projection, selection, selectionArgs, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
private static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
答案 4 :(得分:0)
我不了解 WhatsApp,但是,我通过阅读源代码设法了解 Telegram 如何做到这一点,并且我在我的博客上写了一篇关于他们如何逐步做到这一点的文章,您可以在此处找到{ {3}}。