--- tags: Android --- # 使用CameraX preview 相機畫面 CameraX是Jetpack支援的套件,根據google的描述,該套件是對camera2進行的封裝,它提供了更加簡單的API介面,可於Android 5.0以上等級的系統上執行。 CameraX可與Lifecycle綁定在一起,所以開發人員就不需要去處理何時應該要釋放相機的問題,都交給Lifecycle去處理。 ## 權限 需要的CAMERA權限,如果你要儲存相片,還需要WRITE_EXTERNAL_STORAGE的權限,因為這裡我們只要預覽而已所以只需要以下權限 ``` =xml <uses-permission android:name="android.permission.CAMERA" /> ``` ## 環境需求 CameraX 需要的最低需求: 1. Android API level 21 2. Android Architecture Components 1.1.1 ## Dependencies ``` =groovy def camerax_version = "1.0.0-beta07" // CameraX core library using camera2 implementation implementation "androidx.camera:camera-camera2:$camerax_version" // CameraX Lifecycle Library implementation "androidx.camera:camera-lifecycle:$camerax_version" // CameraX View class implementation "androidx.camera:camera-view:1.0.0-alpha14 ``` ## layout設計 在layout中新增previewView。 ``` =xml <androidx.camera.view.PreviewView android:id="@+id/camerax_previewView" android:layout_width="match_parent" android:layout_height="match_parent"/> ``` ## 開始實作 先取得PerviewView ``` =java private PreviewView mPreviewView; ... private void findView(){ mPreviewView = findViewById(R.id.camerax_previewView); ... } ``` 第二步取得ProcessCameraProvider,用來綁定生命週期跟設定使用前後相機等。 ``` =java //異步執行ProcessCameraProvider.getInstance ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this); ``` 透過上面一段的程式碼,可以看到是利用Future對取得ProcessCameraProvider進行非同步的處理.我們可以透過下方ProcessCameraProvider.getInstance的source code窺探裡面的作法: ``` =java @NonNull public static ListenableFuture<ProcessCameraProvider> getInstance( @NonNull Context context) { Preconditions.checkNotNull(context); return Futures.transform(CameraX.getOrCreateInstance(context), cameraX -> { sAppInstance.setCameraX(cameraX); return sAppInstance; }, CameraXExecutors.directExecutor()); } ``` 所以接下來我們必須要給cameraProviderFuture增加一的監聽,用來監聽ProcessCameraProvider.getInstance(),一旦等到這個非同步的function完成後,可以接著往下執行. ``` =java cameraProviderFuture.addListener(new Runnable() { @Override public void run() { //Preview Preview preview = new Preview.Builder().build(); preview.setSurfaceProvider(mPreviewView.createSurfaceProvider()); } }, ContextCompat.getMainExecutor(this)); ``` 上面第一個參數則是當監聽的function完成後應該要執行的事情,透過Runnable執行.第二個參數則是指定用什麼執行緒執行.接著我們先在Runnable裡面建立好Perview並設定好SurfaceProvider. 接著我們開始對ProcessCameraProvider進行生命週期的綁定以及將剛剛設定好的Preview一起傳進去. ``` =java try { //取得異步執行ProcessCameraProvider.getInstance的執行結果 ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); cameraProvider.unbindAll(); //綁定生命週期並且使用前相機,綁定的生命週期也可以自訂 cameraProvider.bindToLifecycle(MainActivity.this, CameraSelector.DEFAULT_FRONT_CAMERA,preview); } catch (ExecutionException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } ``` 整個function完成後程式碼如下: ``` =java /** * 啟動相機預覽 */ private void startCamera(){ //異步執行ProcessCameraProvider.getInstance ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this); //新增監聽,待ProcessCameraProvider.getInstance執行完成後run以下步驟。 cameraProviderFuture.addListener(new Runnable() { @Override public void run() { //Preview Preview preview = new Preview.Builder().build(); preview.setSurfaceProvider(mPreviewView.createSurfaceProvider()); try { //取得異步執行ProcessCameraProvider.getInstance的執行結果 ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); cameraProvider.unbindAll(); //綁定生命週期並且使用前相機,綁定的生命週期也可以自訂 cameraProvider.bindToLifecycle(MainActivity.this, CameraSelector.DEFAULT_FRONT_CAMERA,preview); } catch (ExecutionException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }, ContextCompat.getMainExecutor(this)); } ``` 以上就是CameraX實現preview的簡單介紹. ## 參考資料 https://developer.android.com/training/camerax https://codelabs.developers.google.com/codelabs/camerax-getting-started#3
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.