Android圖片實現(xiàn)壓縮處理的實例代碼
整理文檔,搜刮出一個Android圖片實現(xiàn)壓縮處理的實例代碼,稍微整理精簡一下做下分享。
詳解:
1.獲取本地圖片F(xiàn)ile文件 獲取BitmapFactory.Options對象 計算原始圖片 目標圖片寬高比 計算輸出的圖片寬高
2.根據(jù)寬高比計算options.inSampleSize值(縮放比例 If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory.)得到bitmap位圖 根據(jù)位圖對象獲取新的輸出位圖對象 Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)Creates a new bitmap, scaled from an existing bitmap, whenpossible.
3.獲取圖片方向調(diào)整、失量壓縮圖片保持在1024kb以下
//進行大小縮放來達到壓縮的目的
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(srcImagePath, options);
//根據(jù)原始圖片的寬高比和期望的輸出圖片的寬高比計算最終輸出的圖片的寬和高
float srcWidth = options.outWidth;
float srcHeight = options.outHeight;
float maxWidth = outWidth;
float maxHeight = outHeight;
float srcRatio = srcWidth / srcHeight; //原始圖片寬高比
float outRatio = maxWidth / maxHeight; //目標圖片寬高比
float actualOutWidth = srcWidth;
float actualOutHeight = srcHeight;
if (srcWidth > maxWidth || srcHeight > maxHeight) {
if(srcRatio>outRatio){ //原始寬高比大于目標寬高比
actualOutWidth = maxWidth;
actualOutHeight = actualOutWidth / srcRatio;
}else if(srcRatio<outRatio){ //原始寬高比小于目標寬高比
actualOutHeight = maxHeight;
actualOutWidth = actualOutHeight * srcRatio;
}
}else{
actualOutWidth = maxWidth;
actualOutHeight = maxHeight;
}
options.inSampleSize = computSampleSize(options, actualOutWidth, actualOutHeight);
options.inJustDecodeBounds = false;
Bitmap scaledBitmap = null;
try {
scaledBitmap = BitmapFactory.decodeFile(srcImagePath, options);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
if (scaledBitmap == null) {
return null;
}
//生成最終輸出的bitmap
Bitmap actualOutBitmap = Bitmap.createScaledBitmap(scaledBitmap, (int) actualOutWidth, (int) actualOutHeight, true);
//釋放原始位圖資源
if(scaledBitmap!=actualOutBitmap){ //判斷目標位圖是否和原始位圖指向棧目標相同
scaledBitmap.recycle();
scaledBitmap = null;
}
//處理圖片旋轉(zhuǎn)問題
ExifInterface exif = null;
try {
exif = new ExifInterface(srcImagePath);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 0);
Matrix matrix = new Matrix();
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
matrix.postRotate(90);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
matrix.postRotate(180);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
matrix.postRotate(270);
}
actualOutBitmap = Bitmap.createBitmap(actualOutBitmap, 0, 0,
actualOutBitmap.getWidth(), actualOutBitmap.getHeight(), matrix, true);
} catch (IOException e) {
e.printStackTrace();
return null;
}
//進行有損壓縮
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options_ = 100;
actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//質(zhì)量壓縮方法,把壓縮后的數(shù)據(jù)存放到baos中 (100表示不壓縮,0表示壓縮到最小)
int baosLength = baos.toByteArray().length;
while (baosLength / 1024 > maxFileSize) {//循環(huán)判斷如果壓縮后圖片是否大于maxMemmorrySize,大于繼續(xù)壓縮
baos.reset();//重置baos即讓下一次的寫入覆蓋之前的內(nèi)容
options_ = Math.max(0, options_ - 10);//圖片質(zhì)量每次減少10
actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//將壓縮后的圖片保存到baos中
baosLength = baos.toByteArray().length;
if (options_ == 0)//如果圖片的質(zhì)量已降到最低則,不再進行壓縮
break;
}
actualOutBitmap.recycle();
//將bitmap保存到指定路徑
FileOutputStream fos = null;
String filePath = getOutputFileName(srcImagePath);
try {
fos = new FileOutputStream(filePath);
//包裝緩沖流,提高寫入速度
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fos);
bufferedOutputStream.write(baos.toByteArray());
bufferedOutputStream.flush();
} catch (FileNotFoundException e) {
return null;
} catch (IOException e) {
return null;
} finally {
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//獲取位圖縮放比例
private int computSampleSize(BitmapFactory.Options options, float reqWidth, float reqHeight) {
float srcWidth = options.outWidth;//20
float srcHeight = options.outHeight;//10
int sampleSize = 1;
if (srcWidth > reqWidth || srcHeight > reqHeight) {
int withRatio = Math.round(srcWidth / reqWidth);
int heightRatio = Math.round(srcHeight / reqHeight);
sampleSize = Math.min(withRatio, heightRatio);
}
return sampleSize;
}
壓縮比例換算:
float srcWidth = options.outWidth;
float srcHeight = options.outHeight;
float widthScale = outWidth / srcWidth;//目標/原始 寬比例
float heightScale = outHeight / srcHeight; //目標原始 高比
//對比寬高比選擇較大的一種比例
float scale = widthScale > heightScale ? widthScale : heightScale;
float actualOutWidth = srcWidth;
float actualOutHeight = srcHeight;
if (scale < 1) {
actualOutWidth = srcWidth * scale;
actualOutHeight = srcHeight * scale;
}
設(shè)置縮放比例--生成新的位圖
Matrix matrix1 = new Matrix();
matrix1.postScale(scale, scale);// 放大縮小比例
//生成最終輸出的bitmap
Bitmap actualOutBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix1, true);
if (actualOutBitmap != scaledBitmap) {
scaledBitmap.recycle();
scaledBitmap = null;
System.gc();
}
參考:https://github.com/guizhigang/LGImageCompressor
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android中解決RecyclerView各種點擊事件的方法
這篇文章主要介紹了Android中解決RecyclerView各種點擊事件的方法,完美解決RecyclerView點擊事件、長按事件、子項點擊事件,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
Android listview數(shù)據(jù)顯示及提示信息的實例
這篇文章主要介紹了Android listview數(shù)據(jù)顯示及提示信息的實例的相關(guān)資料,需要的朋友可以參考下2017-05-05
Android 中HttpURLConnection與HttpClient使用的簡單實例
這篇文章介紹了Android 中HttpURLConnection與HttpClient使用的簡單實例,有需要的朋友可以參考一下2013-10-10
Android 修改系統(tǒng)關(guān)機動畫的實現(xiàn)
這篇文章主要介紹了Android 修改系統(tǒng)關(guān)機動畫的實現(xiàn)的相關(guān)資料,需要的朋友可以參考下2016-10-10
使用Android的OkHttp包實現(xiàn)基于HTTP協(xié)議的文件上傳下載
OkHttp(GitHub主頁https://github.com/square/okhttp)是近來人氣攀升的一款安卓第三方HTTP包,這里我們來講解一下如何使用Android的OkHttp包實現(xiàn)基于HTTP協(xié)議的文件上傳下載:2016-07-07

