在應用程式中新增預覽時,請使用 PreviewView。這種 View 可供裁剪、縮放及旋轉,以便正確顯示圖片。
當相機啟動時,圖片預覽會串流至 PreviewView 內部途徑。
使用 PreviewView
使用 PreviewView 對 CameraX 導入預覽的過程包含下列步驟,詳情請見後續章節:
- (選用) 設定
CameraXConfig.Provider。 - 在版面配置中加入
PreviewView。 - 要求
ProcessCameraProvider。 - 建立
View時確認ProcessCameraProvider。 - 選取相機並繫結至生命週期和用途。
使用 PreviewView 有些許限制。使用 PreviewView 時,您將無法執行下列任一操作:
- 建立
SurfaceTexture,並在TextureView和Preview.SurfaceProvider上進行設定。 - 從
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會使用沒有專屬繪圖介面 (與SurfaceView不同) 的TextureView。因此,必須以混合的方式轉譯才能顯示影片。在這個額外步驟中,應用程式可以執行其他處理程序,例如不受限制地縮放及旋轉影片。
使用 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可顯示的最大尺寸。不過,雖然這種做法可以顯示完整的影片影格,畫面中的某部分可能會呈現空白。根據您在三種縮放類型之中選擇的類型,影片影格會與目標 View 的中心點、起點或結尾對齊。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的尺寸)。 - 配合 1920x1080
PreviewView視窗裁剪 1920x1440 影片影格。- 如果是
FILL_CENTER,以 1920x1440 縮放後影片的中心為準,裁剪出 1920x1080 的大小。這時無法顯示影片上方和底部的 180 行內容。 - 如果是
FILL_START,以 1920x1440 縮放後影片的起點為準,裁剪出 1920x1080 的大小。這時無法顯示影片底部的 360 行內容。 - 如果是
FILL_END,以 1920x1440 縮放後影片的結尾為準,裁剪出 1920x1080 的大小。這時無法顯示影片上方的 360 行內容。
- 如果是
其他資源
如要進一步瞭解 CameraX,請參閱下列其他資源。
程式碼研究室
程式碼範例