android 壓縮圖片壓縮到100K以下,並且寬高不超過1028
阿新 • • 發佈:2019-02-07
在android開發中,經常遇到圖片壓縮問題,由此記錄下以下壓縮方法。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.text.TextUtils;
import android.util.Log;
public class ImageUtils {
/**
* 壓縮圖片到指定的位置
*
* a,圖片寬或者高均小於或等於1280時圖片尺寸保持不變,但仍然經過圖片壓縮處理,得到小檔案的同尺寸圖片
* b,寬或者高大於1280,但是圖片寬度高度比小於或等於2,則將圖片寬或者高取大的等比壓縮至1280
* c,寬或者高大於1280,但是圖片寬高比大於2時,並且寬以及高均大於1280,則寬或者高取小的等比壓縮至
* d,寬或者高大於1280,但是圖片寬高比大於2時,並且寬或者高其中一個小於1280,則壓縮至同尺寸的小檔案圖片
*
* @param filePath 返回壓縮後圖片的路徑
* @return
*/
@SuppressLint("NewApi")
@SuppressWarnings("finally")
public static String compressUpImage(String filePath) {
if (TextUtils.isEmpty(filePath)) return null;
//旋轉角度
int degree = readPictureDegree(filePath);
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPurgeable = true;// 同時設定才會有效
opt.inInputShareable = true;//。當系統記憶體不夠時候圖片自動被回收
opt.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, opt);
opt.inSampleSize = calculateInSampleSize(opt, 1028, 1028);
opt.inJustDecodeBounds = false;
Bitmap cbitmap = BitmapFactory.decodeFile(filePath, opt);
Log.i("==image==","壓縮前的尺寸: 寬: " + opt.outWidth + " ---- 高:" + opt.outHeight);
Bitmap image = null;
Bitmap upImage = null;
int quality = 100;
if (Math.abs(degree) > 0) {
try {
image = rotaingImage(degree, cbitmap);
} catch (Exception e) {
e.printStackTrace();
image = cbitmap;
}
} else {
image = cbitmap;
}
if(image==null) return "";
int width = image.getWidth();
int height = image.getHeight();
File tempFile = null;
if (width <= 1028 && height <= 1028) {
upImage = image;
if(upImage!=null&&upImage.getByteCount()>102400) {
quality = 60;
}
Log.i("==image==","圖片寬或者高均小於或等於1280時圖片尺寸保持不變,但仍然經過圖片壓縮處理,得到小檔案的同尺寸圖片");
} else if ((width > 1028 || height > 1028) && width / height <= 2) {
Log.i("==image==","寬或者高大於1280,但是圖片寬度高度比小於或等於2,則將圖片寬或者高取大的等比壓縮至1280");
int newWidth = 1028;
int newHeight = 1028;
if (width <= height) {
newWidth = (int) ((width * 1028f) / height);
} else {
newHeight = (int) ((height * 1028f) / width);
}
upImage = Bitmap.createScaledBitmap(image, newWidth, newHeight, false);
if (image != null && !image.isRecycled()) {
image.recycle();
}
quality = 60;
} else if (width > 1028 && height > 1028 && width / height > 2) {
Log.i("==image==","寬或者高大於1280,但是圖片寬高比大於2時,並且寬以及高均大於1280,則寬或者高取小的等比壓縮至1280");
int newWidth = 1028;
int newHeight = 1028;
if (width >= height) {
newWidth = (int) ((width * 1028f) / height);
} else {
newHeight = (int) ((height * 1028f) / width);
}
upImage = Bitmap.createScaledBitmap(image, newWidth, newHeight, false);
if (image != null && !image.isRecycled()) {
image.recycle();
}
quality = 60;
} else if ((width > 1028 && height < 1028) || (width < 1028 && height > 1028) && width / height > 2) {
Log.i("==image==","寬或者高大於1280,但是圖片寬高比大於2時,並且寬或者高其中一個小於1280,則壓縮至同尺寸的小檔案圖片");
upImage = image;
quality = 60;
} else {
upImage = image;
quality = 60;
}
Log.i("==image==","壓縮後的尺寸: 寬:" + upImage.getWidth() + " --- 高: " + upImage.getHeight());
FileOutputStream out = null;
try {
//建立臨時檔案
tempFile = File.createTempFile("upImage", ".jpg");
out = new FileOutputStream(tempFile);
upImage.compress(Bitmap.CompressFormat.JPEG, quality, out);
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (tempFile == null) {
return null;
} else {
return tempFile.getAbsolutePath();
}
}
}
/**
* 讀取圖片屬性:旋轉的角度
*
* @param path 圖片絕對路徑
* @return degree旋轉的角度
*/
public static int readPictureDegree(String path) {
int degree = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}
/**
*計算圖片的縮放值
*/
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;
}
return inSampleSize;
}
/*
* 旋轉圖片
* @param angle
* @param bitmap
* @return Bitmap
*/
public static Bitmap rotaingImage(int angle, Bitmap bitmap) {
//旋轉圖片 動作
Matrix matrix = new Matrix();
matrix.postRotate(angle);
Log.i("==image==","angle=" + angle);
// 建立新的圖片
Bitmap returnBm = null;
try {
// 將原始圖片按照旋轉矩陣進行旋轉,並得到新的圖片
returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
if (returnBm == null) {
returnBm = bitmap;
}
if (bitmap != returnBm) {
bitmap.recycle();
}
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
return returnBm;
}
}