1. 程式人生 > >android圖片系統解決方案-從採集到顯示

android圖片系統解決方案-從採集到顯示

概述

Android上圖片涉及到的要點:

  • 自定義相機拍照
  • 呼叫系統相機拍照
  • 圖片選擇
  • 裁剪
  • 壓縮
  • 上傳
  • 服務端處理與下載
  • 顯示與記憶體-普通圖與超大圖
  • 資料夾管理
  • 內建圖片管理與包大小

自定義相機拍照

camera api是Android相容性問題最大的地方,沒有之一.所以,不要作死去用原生的,或者自己從頭開始寫一套. 直接用開源的.

CameraView

注意點:

  • 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都是通過這種形式實現,網上開源庫也一大把.

github.com/zhihu/Matis…

github.com/donglua/Pho…

圖片裁剪

有系統intent,但是不同手機千差萬別,大多數很差勁.果斷用開源的. 開源庫中,ucrop秒殺其他裁剪庫:

github.com/Yalantis/uC…

圖片壓縮

  • 尺寸壓縮與質量壓縮:
  • Android skia庫的bug: 多次壓縮的圖片發綠問題
  • libjpeg-turbo庫在Android上的壓縮優化
  • 模仿微信壓縮效果的庫: Luban

拍照/圖片選擇-圖片裁剪-壓縮 的整合

github.com/crazycodebo…

github.com/LuckSiege/P…

結合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友好

服務端處理與下載

客戶端顯示

資料夾管理

  • 專案中提供統一的獲取方法,刪除方法
  • cache使用的注意事項:儲存不足時會被系統優先清空

內建圖片管理與包大小

  • tinypng/tinyjpg先壓縮一遍
  • 用不到透明通道的png統一轉換成jpg
  • 大一些的圖,可以放到服務端,首次進入app時下載到files資料夾.