Flutter 相機定制


Flutter中與硬件相關的部分,一直都挺蛋疼的。方案基本上有兩種,自己寫,或者等出相關的庫。

最近做的一個項目中,需要對相機做定制。有過相關模塊開發經驗的,就知道這種需求並不簡單,況且是這種跨平台解決方案的初期。

需求來了,怎么辦呢?那就只能硬着頭皮上了。先去pub上找找,有沒有可以使用的庫。初步挑到兩個庫,一個camera,另一個是image_picker。

image_picker試了下,基本上就pass了,只能調用系統相機或者選擇相冊,相機相關部分,肯定是沒法使用。相冊部分倒是可以拿來使用。

camera試着運行了下demo,感覺這個庫可以使用,直接將相機預覽封裝成一個flutter widget。我們可以很方便的在上面進行各種定制。

設計圖上需要相機全屏顯示,試着在demo上修改成全屏,悲劇出現了,風一般的拉伸效果。添加一個調取相機的頁面,在退出相機頁面后,demo置后台,切換到前台的時候,Android這邊crash了,試了N多次,100%的crash,我勒個擦,谷歌官方的插件寫的這么隨意~

然后,重點來了,本文主要是解決這兩個問題,一個是全屏顯示的問題,另一個則是crash問題

先上一張Android端的拍照效果圖:

Flutter 相機定制

Android端全屏拉伸問題

對於這種相機拉伸問題,做過相機定制相關的,都會知道是預覽的分辨率選擇錯誤導致的,知道這一點過后,修改起來就簡單的多了。直接拉camer plugin的源碼,Android的實現,相對還是比較簡單,一個文件700來行代碼。找到計算預覽尺寸的方法。

    private void computeBestPreviewAndRecordingSize(
        StreamConfigurationMap streamConfigurationMap, Size minPreviewSize, Size captureSize) {
        ....
    }

考慮到以后camera插件升級的問題,直接單獨新建一個文件進行最佳預覽尺寸的計算,然后在調用處進行替換即可。

Android端前后台切換必現crash問題

Android端前后台切換的問題,查看log發現是resume過后崩潰的,直接擼源代碼,發現插件監聽了Activity的生命周期,在resume的時候進行了open操作。

  @Override
  public void onActivityResumed(Activity activity) {
    if (requestingPermission) {
      requestingPermission = false;
      return;
    }
    if (activity == CameraPlugin.this.activity) {
      if (camera != null) {
        camera.open(null);
      }
    }
  }

問題來了,關鍵是,插件沒有進行unregister操作,在退出相機頁面過后,調用dispose方法,會將camera關閉,並且將cameraDevice置為null,其他生命周期回調中調用cameraDevice的都會crash。onActivityResumed調用camer.open也會crash。這些crash的根本原因是因為沒有將回調unregister掉。了解這些過后,修改起來就簡單了,在dispose的時候,將插件的生命周期回調給unregister掉。修改完成后,試下效果,果然都沒有crash。

后話

相關代碼段我就不貼出來了,關於全屏預覽尺寸的計算,網上太多的資料了,將previewSize計算正確即可。第二個crash的問題,添加一個unregisterActivityLifecycleCallbacks即可。對於修改的地方,做好注釋,后續升級插件合入的時候不錯亂即可。

目前來看Flutter第三方真的很差,如果只是自己個人項目,或者一些偏向於數據展示的項目,可以試一下。但是對於商業項目,尤其是硬件依賴性比較強的,還是建議一段時間過后再看看。

大后話

谷歌官方的camera插件,如果只是自己使用的話,可以按照上面的方法去修改,如果想要用在商業項目上,還是勸三思。

谷歌官方camera插件Android部分,用的是camera2 API,這個API有什么問題呢?

  1. 從21開始支持,也就是說需要放棄百分之十幾的份額;
  2. 上面版本不是最坑的,最坑的是什么呢?硬件廠商對camera2的支持程度,遇到幾台機子,對camera2支持非常差,這些機子還是近一年比較新的機子(vivo x20a),獲取到的最大預覽分辨率非常低,拍出來的圖片尺寸也對不上。

最后,重寫了Android部分,直接采用camera API,支持版本從16開始,完全沒啥問題,對硬件支持也都非常完美。谷歌這個坑埋的有點深,最開始考慮時間因素,結果花在插件上修改分辨率、修改crash、排查特殊機型問題的時間不少。

參考

  1. Android設備對新Camera2 API的支持問題:以華為M2為例


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM