近日在做一款飯否第三方客戶端,飯否對于圖片上傳有著嚴格的大小限制(店小成本問題,┑( ̄Д  ̄)┍),GIF大小2M,靜態(tài)圖4M,即便如此,大部分拍照的圖片都是超過4M大小的。
最開始使用的是Luban,但是經(jīng)常出現(xiàn)該庫讀取Exif信息的時候出錯崩潰,導致壓根不壓縮,所以想著自己寫。
網(wǎng)上有一個壓縮圖片的片段比較好,思想是對JPEG圖片的質(zhì)量參數(shù)進行嘗試,從100開始,做循環(huán)壓縮,每次降低10,直到大小符合要求,代碼如下:
public static void compressBmpToFile(Bitmap bmp,File file){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options = 80;//個人喜歡從80開始,
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
while (baos.toByteArray().length / 1024 > 100) {
baos.reset();
options -= 10;
bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
但是在實踐過程中,發(fā)現(xiàn)此段代碼有較為嚴重的性能問題,核心在于baos.toByteArray().length
,查閱Android文檔如下:
toByteArray()
作為一個嘗試獲取壓縮后大小的操作每次都重新分配大小是不合適的,需要獲取壓縮后占用空間,可以直接使用ByteArrayOutputStream.size()
即可,查閱其源代碼,size()
返回流內(nèi)部數(shù)組的大小,免去了重復分配且復制的操作。