支援多種板型規格的相機

Android 應用程式可執行的板型規格不只直向放置的手機。 隨著電腦分割視窗模式、外接螢幕和摺疊式裝置的推出,相機應用程式必須配合動態視窗大小、不同顯示比例和外部硬體調整。

圖 1. 不同螢幕上的攝影機應用程式範例。

電話邏輯中斷的原因

相機應用程式經常會做出假設,導致多種外型規格環境發生重大錯誤。

自然方向

  • 假設:裝置的自然方向 ROTATION_0 一律為直向
  • 實際情況:在平板電腦、部分摺疊裝置的內螢幕和桌上型螢幕上,ROTATION_0 通常會以橫向顯示
  • 結果:預覽畫面未正確旋轉 90 度
圖 2. 套用正確旋轉角度前後的相機觀景窗。

感應器對齊

  • 假設:相機感應器的長邊與螢幕的長邊對齊
  • 實際情況:可調整大小的視窗可以是正方形或橫向,感應器則保持固定 (通常為 4:3)
  • 結果:圖片遭到延展或變形
圖 3. 套用正確的縮放比例前後的相機觀景窗。

螢幕密度和大小

  • 假設:螢幕的密度和大小不會在執行階段變更
  • 事實:在電腦環境中,使用者可以自由調整視窗大小
  • 結果:在每個拖曳事件中重新啟動攝影機工作階段,會中斷使用者體驗,並可能導致當機

解決方案 1:使用系統意圖

如果應用程式需要拍攝相片或影片,但不需要專用的自訂相機介面,處理不同外型的最佳方式是啟動裝置預先安裝的系統相機 (請參閱「相機意圖」)

使用系統意圖可將整個擷取體驗委派給裝置原始設備製造商 (OEM) 開發的相機應用程式。這項功能可有效外包表單因子的支援複雜度,包括:

  • 內建大小調整和旋轉支援:摺疊式裝置或平板電腦上的預設相機應用程式,是由製造商專為處理特定裝置的幾何形狀而建構。應用程式的設計可確保裝置展開、旋轉或進入多視窗模式時,應用程式能正常運作。

  • 存取進階硬體功能:OEM 相機應用程式可專屬存取硬體調整演算法 (夜間模式、HDR、特定鏡頭切換),這些演算法難以或無法手動複製。

解決方案 2:使用 Jetpack CameraX

CameraX 是 Jetpack 程式庫,旨在簡化相機應用程式的開發作業。CameraX 可感知生命週期,並以 Surface 為導向。 與 Camera2 不同,每當裝置摺疊、旋轉或調整大小時,CameraX 會自動處理攝影機工作階段的重新設定,確保預覽串流會適應,不會發生延遲或延展的情況。Camera2 則需要手動重新計算感應器方向和表面大小。

PreviewView 等元件會智慧管理不同狀態下的長寬比和縮放類型,例如折疊式裝置從封面螢幕轉換到內螢幕時,可讓您透過單一一致的實作方式支援各種硬體,不必處理複雜的裝置專屬特殊情況。

撰寫

使用 Jetpack Compose 時,請使用專屬的 androidx.camera:camera-compose 程式庫。這個程式庫提供 CameraXViewfinder 可組合函式,專門處理 Compose 生命週期內的複雜幾何形狀,例如大小調整、旋轉和長寬比。

CameraXViewfinder 元件可消除相機應用程式中最常見的錯誤來源:

  • 自動座標轉換:建構相機應用程式最困難的部分之一,就是將使用者的輕觸 (螢幕上的 x、y 座標) 對應至相機感應器的座標系統 (0-1、0-1 旋轉),以進行對焦和測光。CameraXViewfinder 提供 CoordinateTransformer,即使視窗大小調整或裝置折疊,也能自動處理數學運算。
  • 正確的版面配置行為:與 SurfaceViewTextureView 不同,CameraXViewfinder 可與 Compose 的 z 排序正確搭配使用。您可以疊加 UI 元素 (焦點環、控制項) 或套用修飾符 (圓角、動畫),而不會產生算繪構件。
  • 調整大小和顯示比例CameraXViewfinder 會在內部處理中央裁剪配合中央邏輯,確保應用程式視窗調整為非標準顯示比例時 (例如分割畫面或桌面視窗模式),預覽畫面不會延展。

View

如果是以 View 為基礎的應用程式,請使用 PreviewViewViewFinderView。 如果您直接使用 SurfaceViewTextureView,就必須自行計算長寬比,並套用正確的轉換矩陣

解決方案 3:動態處理螢幕方向和大小調整

直接使用平台 API 時,請留意裝置旋轉、活動重新啟動和螢幕比例。

停止使用裝置旋轉功能

請勿單獨依賴 Display#getRotation() 或實體感應器方向來決定 UI 版面配置。

  • 使用視窗指標:比較應用程式視窗的寬度和高度,藉此判斷版面配置 (橫向與直向 UI),請使用 WindowManager#getCurrentWindowMetrics()
  • 忽略自然方向:您的應用程式可能會在橫向螢幕上以直向視窗顯示。裝置螢幕方向與 UI 邊界無關。

避免活動重新啟動

根據預設,Android 會在設定變更 (例如調整視窗大小) 時刪除應用程式的活動。如果是相機應用程式,則會顯示螢幕閃爍或視訊通話期間連線中斷。

顯示比例和裁剪

在摺疊式裝置和電腦視窗上,常見的問題是預覽畫面遭到延展,也就是 4:3 的攝影機畫面強制進入 16:9 或 1:1 的視窗。

  • 請勿延展:如果預覽畫面和視窗的顯示比例不同,請勿強制攝影機緩衝區完全符合檢視範圍。
  • 中央裁剪 (建議):縮放預覽畫面,填滿視窗最短的維度,並裁剪多餘部分。確保主體不會失真,並填滿畫面。
  • 置中顯示 (替代方案):如果必須顯示完整視野 (例如掃描文件),請在視窗內以上下黑邊顯示預覽畫面。
  • 置中顯示 (替代方案):如果必須顯示完整視野 (例如掃描文件),請在視窗內以上下黑邊顯示預覽畫面。

加分功能:支援摺疊裝置優先體驗

摺疊式裝置不只是可以彎曲的手機,還提供獨特的硬體狀態,從根本上改善使用者拍攝相片和影片的方式。請勿將摺疊視為待解決的問題,而是利用這項特性建構非摺疊裝置無法提供的功能。

免持模式 (免持拍攝)

免手持模式:使用者可將裝置半摺疊並放在平面上,進行長時間的視訊通話、縮時攝影,以及長時間曝光的夜間攝影。

圖 5. 免手持模式下的通訊應用程式:相機觀景窗位於螢幕頂端,控制項則位於底部。

後置螢幕模式 (高畫質自拍照)

  • 在摺疊式手機上,後置鏡頭的畫質通常比前置鏡頭高。 後置螢幕模式可讓使用者展開裝置並轉向,將小型封面螢幕當做後置主鏡頭的即時觀景窗。
  • 有了後螢幕模式,你就能拍攝 5000 萬像素以上的自拍、超廣角團體照,以及高品質的 Vlog,不必攜帶額外裝備。

雙螢幕模式 (主題預覽)

  • 雙螢幕模式可讓您同時在內螢幕和外螢幕上顯示相機預覽畫面。這項功能非常適合拍攝人物: 拍攝對象可以在外螢幕上看到自己並調整姿勢, 而你則在內螢幕上取景。
  • 與後螢幕模式 (會移動整個應用程式) 不同,雙螢幕模式會在封面螢幕上建立次要呈現視窗。
圖 5. 雙螢幕模式下的相機應用程式。