在應用程式中新增預覽時,請使用 PreviewView
。這種 View
可供裁剪、縮放及旋轉,以便正確顯示圖片。
當相機啟動時,圖片預覽會串流至 PreviewView
內部途徑。
使用 PreviewView
使用 PreviewView
對 CameraX 導入預覽時,以下步驟會進行說明,詳情請見後續章節:
- 選用設定
CameraXConfig.Provider
。 - 在版面配置中新增
PreviewView
。 - 要求
ProcessCameraProvider
。 - 在
View
建立時查看ProcessCameraProvider
。 - 請選取相機並繫結至生命週期和用途。
使用 PreviewView
有些許限制。使用 PreviewView
時,您將無法執行下列任一操作:
- 在
TextureView
和Preview.SurfaceProvider
中建立要設定的SurfaceTexture
。 - 從
TextureView
擷取SurfaceTexture
並於Preview.SurfaceProvider
上進行設定。 - 從
SurfaceView
取得Surface
並於Preview.SurfaceProvider
上進行設定。
如果發生上述任一情況,Preview
將停止串流畫面至 PreviewView
。
在版面配置中新增 PreviewView
下列範例顯示版面配置中的 PreviewView
:
<FrameLayout android:id="@+id/container"> <androidx.camera.view.PreviewView android:id="@+id/previewView" /> </FrameLayout>
要求 CameraProvider
下列程式碼顯示要求 CameraProvider
方式:
Kotlin
import androidx.camera.lifecycle.ProcessCameraProvider import com.google.common.util.concurrent.ListenableFuture class MainActivity : AppCompatActivity() { private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider> override fun onCreate(savedInstanceState: Bundle?) { cameraProviderFuture = ProcessCameraProvider.getInstance(this) } }
Java
import androidx.camera.lifecycle.ProcessCameraProvider import com.google.common.util.concurrent.ListenableFuture public class MainActivity extends AppCompatActivity { private ListenableFuture<ProcessCameraProvider> cameraProviderFuture; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { cameraProviderFuture = ProcessCameraProvider.getInstance(this); } }
檢查 CameraProvider 適用性
要求 CameraProvider
後,請在建立檢視畫面時確認初始化成功。以下程式碼說明如何執行這項作業:
Kotlin
cameraProviderFuture.addListener(Runnable { val cameraProvider = cameraProviderFuture.get() bindPreview(cameraProvider) }, ContextCompat.getMainExecutor(this))
Java
cameraProviderFuture.addListener(() -> { try { ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); bindPreview(cameraProvider); } catch (ExecutionException | InterruptedException e) { // No errors need to be handled for this Future. // This should never be reached. } }, ContextCompat.getMainExecutor(this));
如需此範例中使用的 bindPreview
函式範例,請參閱下一節提供的程式碼。
請選取相機並繫結至生命週期和用途
建立並確認 CameraProvider
後,請執行以下操作:
- 建立
Preview
。 - 指定想要的相機
LensFacing
選項。 - 將所選相機和任何用途繫結至生命週期。
- 將
Preview
連結至PreviewView
。
下列程式碼範例說明:
Kotlin
fun bindPreview(cameraProvider : ProcessCameraProvider) { var preview : Preview = Preview.Builder() .build() var cameraSelector : CameraSelector = CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build() preview.setSurfaceProvider(previewView.getSurfaceProvider()) var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview) }
Java
void bindPreview(@NonNull ProcessCameraProvider cameraProvider) { Preview preview = new Preview.Builder() .build(); CameraSelector cameraSelector = new CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build(); preview.setSurfaceProvider(previewView.getSurfaceProvider()); Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview); }
請注意,bindToLifecycle()
會回傳 Camera
物件。請參閱此使用手冊,進一步瞭解如何控制相機輸出內容 (例如縮放和曝光)。
您已完成導入相機預覽。建構應用程式,並確認應用程式和功能中顯示的預覽可以正常運作。
PreviewView 的其他控制項
CameraX PreviewView
提供了一些額外的 API 來設定屬性,例如:
實作模式
PreviewView
可以使用下列其中一種模式,將預覽串流轉譯至目標 View
:
預設模式為
PERFORMANCE
。PreviewView
使用SurfaceView
顯示影片串流,但在某些情況下會改為TextureView
。SurfaceView
具有專屬的繪圖介面,較有可能透過內部硬體合成器導入硬體重疊圖層,當預覽影片頂層沒有其他 UI 元素 (例如按鈕) 時更是如此。只要透過硬體重疊圖層進行算繪,影片畫面就會避免使用 GPU 路徑,進而降低平台耗電量和延遲時間。COMPATIBLE
模式。在此模式下,PreviewView
採用無專屬繪圖路徑的TextureView
,與SurfaceView
不同。因此,影片以混合的方式轉譯才能顯示。在此額外步驟中,應用程式可以執行其他處理作業,例如不受限制地縮放及旋轉影片。
使用 PreviewView.setImplementationMode()
選取適合您應用程式的實作模式。如果預設的 PERFORMANCE
模式不適用於您的應用程式,下列程式碼範例說明如何設定 COMPATIBLE
模式:
Kotlin
// viewFinder is a PreviewView instance viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE
縮放類型
如果預覽影片的解析度與目標 PreviewView
的尺寸不同,影片內容就必須經過裁剪或新增上下黑邊 (保持原始長寬比),才能與檢視畫面相符。為此,PreviewView
提供下列 ScaleTypes
:
FIT_CENTER
、FIT_START
和FIT_END
可以用於上下黑邊。完整的影片內容將縮放 (向上或向下) 至目標PreviewView
可顯示的最大可能尺寸。不過,在顯示完整影格時,螢幕中的部分內容可能會呈現空白。根據選擇的三種縮放類型,影格會與目標「檢視畫面」的中心點、起點或結尾對齊。FILL_CENTER
、FILL_START
、FILL_END
可以用於裁剪。如果影片不符合PreviewView
的長寬比,則系統只會顯示部分內容,但影片會填滿整個PreviewView
。
CameraX 採用的預設縮放類型為 FILL_CENTER
。使用 PreviewView.setScaleType()
設定最適合您應用程式的縮放類型。下列程式碼範例會設定 FIT_CENTER
縮放類型:
Kotlin
// viewFinder is a PreviewView instance viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER
顯示影片的程序包括下列步驟:
- 縮放影片:
- 如果是
FIT_*
縮放類型,請使用min(dst.width/src.width, dst.height/src.height)
縮放影片。 - 如果是
FILL_*
縮放類型,請使用max(dst.width/src.width, dst.height/src.height)
縮放影片。
- 如果是
- 將縮放後的影片與目的地
PreviewView
對齊:- 如果是
FIT_CENTER/FILL_CENTER
,縮放後的影片與目的地PreviewView
置中對齊。 - 如果是
FIT_START/FILL_START
,縮放後的影片與目的地PreviewView
相對於每個影片的左上角對齊。 - 如果是
FIT_END/FILL_END
,縮放後的影片與目的地PreviewView
相對於每個影片的右下角對齊。
- 如果是
舉例來說,此為 640x480 來源影片和 1920x1080 目的地 PreviewView
:
下圖顯示了 FIT_START
/ FIT_CENTER
/ FIT_END
縮放程序:
整體程序的運作方式如下:
- 使用
min(1920/640, 1080/480) = 2.25
縮放影片畫面 (保留原始長寬比),以取得 1440x1080 的中繼影片畫面。 - 將 1440x1080 影片畫面與 1920x1080
PreviewView
對齊。- 針對
FIT_CENTER
,請將影片畫面與PreviewView
視窗的中心對齊。PreviewView
的起始和結束 240 像素欄為空白。 - 針對
FIT_START
,請將影片畫面與PreviewView
視窗的起始 (左上角) 對齊。PreviewView
的結束 480 像素欄為空白。 - 針對
FIT_END
,請將影片畫面與PreviewView
視窗的結束 (右下角) 對齊。PreviewView
的起始 480 像素欄為空白。
- 針對
下圖顯示了 FILL_START
/ FILL_CENTER
/ FILL_END
縮放程序:
整體程序的運作方式如下:
- 使用
max(1920/640, 1080/480) = 3
縮放影片畫面,以取得 1920x1440 的中繼畫面 (大於PreviewView
的尺寸)。 - 裁剪 1920x1440 影片畫面,以符合 1920x1080
PreviewView
的視窗。- 針對
FILL_CENTER
,請從 1920x1440 縮放影片的中心部分裁剪 1920x1080。影片的上方和底部 180 行不會顯示。 - 針對
FILL_START
,請從 1920x1440 縮放影片的開始部分裁剪 1920x1080。影片的底部 360 行不會顯示。 - 對於
FILL_END
,請從 1920x1440 縮放影片的結尾部分裁剪 1920x1080。影片上方的 360 行不會顯示。
- 針對
其他資源
如要進一步瞭解 CameraX,請參閱下列其他資源。
程式碼研究室
程式碼範例