看板 KnucklesNote
作者 標題 [AndroidStudio] 將圖檔的寬高縮小 bitmap resize
時間 2016-09-13 Tue. 13:16:08
手機相機存的圖片解析度都很大
如果直接顯示出來會浪費記憶體
上傳到網路上會傳很久
所以必需先做縮圖的處理
參考 Android Developer 如何有效率的載入大圖檔
https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
這個方法只能簡單的將圖片的寬高減半
private Bitmap getScaledBitmap(String imagePath) {
// 取得原始圖檔的大小
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //只抓長度和寬度
BitmapFactory.decodeFile(imagePath, options);
int width = options.outWidth;
// 新圖的寬要小於等於這個值
final int MAX_WIDTH = 1024;
// 求出要縮小的 scale 值,必需是2的次方,ex: 1,2,4,8,16...
int scale = 1;
while(width > MAX_WIDTH){
width /= 2;
scale *= 2;
}
// 使用 scale 值產生縮小的圖檔
BitmapFactory.Options scaledOptions = new BitmapFactory.Options();
scaledOptions.inSampleSize = scale;
return BitmapFactory.decodeFile(imagePath, scaledOptions);
}
// 取得原始圖檔的大小
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //只抓長度和寬度
BitmapFactory.decodeFile(imagePath, options);
int width = options.outWidth;
// 新圖的寬要小於等於這個值
final int MAX_WIDTH = 1024;
// 求出要縮小的 scale 值,必需是2的次方,ex: 1,2,4,8,16...
int scale = 1;
while(width > MAX_WIDTH){
width /= 2;
scale *= 2;
}
// 使用 scale 值產生縮小的圖檔
BitmapFactory.Options scaledOptions = new BitmapFactory.Options();
scaledOptions.inSampleSize = scale;
return BitmapFactory.decodeFile(imagePath, scaledOptions);
}
前面取得原始圖檔大小時,因為使用了 options.inJustDecodeBounds = true;
所以 BitmapFactory.decodeFile(imagePath, options)
只會將寬高存入 options,然後傳出出 null 值
可避免將原本太大的圖檔載入記憶體
但因為只是簡單的將像素減半,縮圖的品質不會很好
如果要縮小成指定的寬高值時,參考
http://stackoverflow.com/questions/4837715/how-to-resize-a-bitmap-in-android
改成
private Bitmap getResizedBitmap(String imagePath) {
// 取得原始圖檔的bitmap與寬高
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
int width = options.outWidth, height = options.outHeight;
// 將圖檔等比例縮小至寬度為1024
final int MAX_WIDTH = 1024;
float resize = 1; // 縮小值 resize 可為任意小數
if(width>MAX_WIDTH){
resize = ((float) MAX_WIDTH) / width;
}
// 產生縮圖需要的參數 matrix
Matrix matrix = new Matrix();
matrix.postScale(resize, resize); // 設定寬高的縮放比例
// 產生縮小後的圖
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
return resizedBitmap;
}
// 取得原始圖檔的bitmap與寬高
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
int width = options.outWidth, height = options.outHeight;
// 將圖檔等比例縮小至寬度為1024
final int MAX_WIDTH = 1024;
float resize = 1; // 縮小值 resize 可為任意小數
if(width>MAX_WIDTH){
resize = ((float) MAX_WIDTH) / width;
}
// 產生縮圖需要的參數 matrix
Matrix matrix = new Matrix();
matrix.postScale(resize, resize); // 設定寬高的縮放比例
// 產生縮小後的圖
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
return resizedBitmap;
}
其中 Bitmap.createBitmap 的最後一個參數設為 true 時可產生品質比較好的縮圖
以下兩張縮圖分別為設為 false 與 true 時:
![[圖]](http://i.imgur.com/IfKeqZc.jpg)
![[圖]](http://i.imgur.com/R2YoElq.jpg)
整合以上兩種方法,當圖檔非常大時 (寬度>MAX_WIDTH*2)
先用方法一產生不那麼大的檔 (寬度<=MAX_WIDTH*2)
再用方法二縮至指定的大小 (寬度<=MAX_WIDTH)
private Bitmap getResizedBitmap(String imagePath) {
final int MAX_WIDTH = 1024; // 新圖的寬要小於等於這個值
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //只讀取寬度和高度
BitmapFactory.decodeFile(imagePath, options);
int width = options.outWidth, height = options.outHeight;
// 求出要縮小的 scale 值,必需是2的次方,ex: 1,2,4,8,16...
int scale = 1;
while(width > MAX_WIDTH*2){
width /= 2;
height /= 2;
scale *= 2;
}
// 使用 scale 值產生縮小的圖檔
BitmapFactory.Options scaledOptions = new BitmapFactory.Options();
scaledOptions.inSampleSize = scale;
Bitmap scaledBitmap = BitmapFactory.decodeFile(imagePath, scaledOptions);
float resize = 1; //縮小值 resize 可為任意小數
if(width>MAX_WIDTH){
resize = ((float) MAX_WIDTH) / width;
}
Matrix matrix = new Matrix(); // 產生縮圖需要的參數 matrix
matrix.postScale(resize, resize); // 設定寬與高的縮放比例
// 產生縮小後的圖
return Bitmap.createBitmap(scaledBitmap, 0, 0, width, height, matrix, true);
}
final int MAX_WIDTH = 1024; // 新圖的寬要小於等於這個值
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //只讀取寬度和高度
BitmapFactory.decodeFile(imagePath, options);
int width = options.outWidth, height = options.outHeight;
// 求出要縮小的 scale 值,必需是2的次方,ex: 1,2,4,8,16...
int scale = 1;
while(width > MAX_WIDTH*2){
width /= 2;
height /= 2;
scale *= 2;
}
// 使用 scale 值產生縮小的圖檔
BitmapFactory.Options scaledOptions = new BitmapFactory.Options();
scaledOptions.inSampleSize = scale;
Bitmap scaledBitmap = BitmapFactory.decodeFile(imagePath, scaledOptions);
float resize = 1; //縮小值 resize 可為任意小數
if(width>MAX_WIDTH){
resize = ((float) MAX_WIDTH) / width;
}
Matrix matrix = new Matrix(); // 產生縮圖需要的參數 matrix
matrix.postScale(resize, resize); // 設定寬與高的縮放比例
// 產生縮小後的圖
return Bitmap.createBitmap(scaledBitmap, 0, 0, width, height, matrix, true);
}
--
※ 作者: Knuckles 時間: 2016-09-13 13:16:08
※ 編輯: Knuckles 時間: 2016-09-14 09:26:24
※ 看板: KnucklesNote 文章推薦值: 0 目前人氣: 0 累積人氣: 1881
回列表(←)
分享