android圖片系統解決方案-從採集到顯示
阿新 • • 發佈:2019-01-03
概述
Android上圖片涉及到的要點:
- 自定義相機拍照
- 呼叫系統相機拍照
- 圖片選擇
- 裁剪
- 壓縮
- 上傳
- 服務端處理與下載
- 顯示與記憶體-普通圖與超大圖
- 資料夾管理
- 內建圖片管理與包大小
自定義相機拍照
camera api是Android相容性問題最大的地方,沒有之一.所以,不要作死去用原生的,或者自己從頭開始寫一套. 直接用開源的.
注意點:
- preview和takepicture兩套不同的操作,不同的supportedSize.
- takepicture的自拍映象問題
- 影象矩陣橫屏90°.方向旋轉可以用純java陣列轉換,也可以用opencv 的api,或者renderscript,或者利用bitmap中轉.
- 最終影象質量:如果對圖片質量(清晰度,亮度)有所要求,可以使用preview的api來採集多幀,取評價最高的一幀作為最終的結果. 評價標準方面,可以基於opencv開發一套對清晰度和亮度判斷的演算法. 更牛的就是多幀合成,頂級實踐就是谷歌,華為,小米的超級夜景演算法.
呼叫系統相機拍照
注意相容性:
- 構建intent時指定檔案儲存位置,避免有些機型拿不到預設儲存位置的返回
- Uri 在7.0以上系統的相容
- 8.0以上系統,即使是呼叫系統相機拍照,也需要請求許可權,否則crash
Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri photoUri = getMediaFileUri(TYPE_TAKE_PHOTO);
takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(takeIntent, CODE_TAKE_PHOTO);
複製程式碼
圖片選擇
可以呼叫系統intent去相簿裡選一張圖,但是不同手機的相簿選擇千差萬別,返回的uri依據手機廠商和版本的不同而情況不同,有的是contentprovider形式,有的是file uri形式,Android 7.0以上以下還不一致. 另外,系統intent不支援多選. 搞來搞去,不如自己查media center資料庫,自己做ui. 基本上成熟的app都是通過這種形式實現,網上開源庫也一大把.
圖片裁剪
有系統intent,但是不同手機千差萬別,大多數很差勁.果斷用開源的. 開源庫中,ucrop秒殺其他裁剪庫: github.com/Yalantis/uC…
圖片壓縮
- 尺寸壓縮與質量壓縮:
- Android skia庫的bug: 多次壓縮的圖片發綠問題
- libjpeg-turbo庫在Android上的壓縮優化
- 模仿微信壓縮效果的庫: Luban
拍照/圖片選擇-圖片裁剪-壓縮 的整合
結合app業務的二次封裝技巧: 透明fragment接收onactivityResult,達到最終靜態方法+回撥的一行程式碼呼叫的效果:
TakePhotoUtil.startPickOne(fragmentActivity, isForCamera, new TakeOnePhotoListener() {
@Override
public void onSuccess(String usableFilePath) {
showImg(usableFilePath);
}
@Override
public void onFail(String filePath, String msg) {
MyToast.errorBigL(msg);
//toTakePhotoMode();
}
@Override
public void onCancel() {
// toTakePhotoMode();
}
});
複製程式碼
ps. 透明fragment的封裝技巧參考: RxPermissionsFragment
圖片上傳
- 控制圖片源,儘量小
- 多圖併發,結合rxjava
- 頂層封裝,api友好
服務端處理與下載
- CDN快取
- 提供服務端處理能力:resize,裁剪,模糊.七牛和阿里雲的圖片儲存服務均提供了此類功能.客戶端通過url後新增引數,獲得比原圖小的圖片,節省流量. 78re52.com1.z0.glb.clouddn.com/resource/go… 示例:QiniuUtils
客戶端顯示
- 普通圖片: fresco/glide. 自己封裝一層,便於切換
- 大圖: 分割槽域解碼 subsampling-scale-image-view
資料夾管理
- 專案中提供統一的獲取方法,刪除方法
- cache使用的注意事項:儲存不足時會被系統優先清空
內建圖片管理與包大小
- tinypng/tinyjpg先壓縮一遍
- 用不到透明通道的png統一轉換成jpg
- 大一些的圖,可以放到服務端,首次進入app時下載到files資料夾.