Triển khai bản xem trước

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Khi thêm bản xem trước vào ứng dụng, hãy dùng PreviewView. Đây là View có thể cắt, điều chỉnh theo tỷ lệ và xoay để hiển thị phù hợp.

Bản xem trước hình ảnh sẽ truyền đến một khu vực bên trong PreviewView khi máy ảnh hoạt động.

Sử dụng PreviewView

Quy trình triển khai bản xem trước cho CameraX bằng PreviewView bao gồm các bước dưới đây. Các bước này được đề cập ở những phần sau:

  1. Định cấu hình CameraXConfig.Provider (không bắt buộc).
  2. Thêm PreviewView vào bố cục.
  3. Yêu cầu ProcessCameraProvider.
  4. Khi tạo View, hãy kiểm tra xem có ProcessCameraProvider hay không.
  5. Chọn một máy ảnh rồi liên kết vòng đời và trường hợp sử dụng.

Việc sử dụng PreviewView có một số hạn chế. Khi dùng PreviewView, bạn không thể thực hiện bất cứ điều nào sau đây:

  • Tạo một SurfaceTexture để đặt trên TextureViewPreview.SurfaceProvider.
  • Truy xuất SurfaceTexture từ TextureView và đặt trên Preview.SurfaceProvider.
  • Lấy Surface từ SurfaceView và đặt trên Preview.SurfaceProvider.

Nếu xảy ra bất kỳ trường hợp nào ở trên, thì Preview sẽ ngừng truyền khung hình đến PreviewView.

Thêm PreviewView vào bố cục

Mẫu sau đây minh hoạ PreviewView trong bố cục:

<FrameLayout
    android:id="@+id/container">
        <androidx.camera.view.PreviewView
            android:id="@+id/previewView" />
</FrameLayout>

Yêu cầu CameraProvider

Mã sau đây minh hoạ cách yêu cầu một 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);
    }
}

Kiểm tra xem CameraProvider có dùng được hay không

Sau khi yêu cầu CameraProvider, hãy xác minh rằng quá trình khởi động đã thành công khi thành phần hiển thị được tạo. Mã sau đây minh hoạ cách thực hiện việc này:

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));

Để biết ví dụ về hàm bindPreview dùng trong mẫu này, hãy xem mã được cung cấp trong phần tiếp theo.

Chọn một máy ảnh rồi liên kết vòng đời và trường hợp sử dụng

Sau khi bạn tạo và xác nhận CameraProvider, hãy làm như sau:

  1. Tạo Preview.
  2. Chỉ định tuỳ chọn LensFacing cho máy ảnh mà bạn muốn dùng.
  3. Liên kết máy ảnh đã chọn và mọi trường hợp sử dụng với vòng đời.
  4. Kết nối Preview với PreviewView.

Mã sau đây cho thấy một ví dụ:

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);
}

Lưu ý rằng bindToLifecycle() trả về đối tượng Camera. Hãy xem hướng dẫn này để biết thêm thông tin về cách kiểm soát đầu ra của máy ảnh, chẳng hạn như thu phóng và độ phơi sáng.

Giờ thì bạn đã triển khai xong bản xem trước cho máy ảnh. Hãy tạo ứng dụng và xác nhận rằng bản xem trước xuất hiện trong ứng dụng của bạn và hoạt động như dự kiến.

Chế độ kiểm soát bổ sung cho PreviewView

PreviewView của CameraX cung cấp một số API bổ sung để định cấu hình các thuộc tính như:

Chế độ triển khai

PreviewView có thể dùng một trong các chế độ sau để hiển thị luồng xem trước trên View đích:

  • PERFORMANCE là chế độ mặc định. PreviewView dùng SurfaceView để hiển thị luồng video, nhưng sẽ quay lại dùng TextureView trong một số trường hợp nhất định. SurfaceView có khu vực vẽ chuyên dụng, giúp tăng cơ hội được trình tổng hợp phần cứng nội bộ triển khai thông qua lớp phủ phần cứng, đặc biệt khi không có thành phần khác trên giao diện người dùng (như nút) phía trên video xem trước. Bằng cách hiển thị qua lớp phủ phần cứng, khung hình video sẽ tránh được lộ trình GPU, nhờ đó giảm mức tiêu thụ điện năng và độ trễ của nền tảng.

  • Chế độ COMPATIBLE. Ở chế độ này, PreviewView dùng TextureView (khác với SurfaceView) không có khu vực vẽ chuyên dụng. Do đó, video sẽ được kết xuất bằng tính năng kết hợp để có thể hiển thị. Trong bước bổ sung này, ứng dụng có thể xử lý thêm, chẳng hạn như điều chỉnh theo tỷ lệ và xoay video mà không bị hạn chế.

Hãy dùng PreviewView.setImplementationMode() để chọn chế độ triển khai phù hợp với ứng dụng của bạn. Nếu chế độ PERFORMANCE mặc định không phù hợp với ứng dụng của bạn, thì mã mẫu sau đây sẽ hướng dẫn bạn cách đặt chế độ COMPATIBLE:

Kotlin

// viewFinder is a PreviewView instance
viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE

Loại tỷ lệ

Khi độ phân giải của video xem trước khác với kích thước của PreviewView đích, thì nội dung video cần phải vừa với thành phần hiển thị bằng cách cắt hoặc dùng hộp chạy chữ (duy trì tỷ lệ khung hình gốc). PreviewView cung cấp ScaleTypes sau cho mục đích này:

  • FIT_CENTER, FIT_STARTFIT_END cho trường hợp dùng hộp chạy chữ. Toàn bộ nội dung video được điều chỉnh theo tỷ lệ (lên hoặc xuống) ở kích thước tối đa có thể hiển thị trong PreviewView đích. Tuy nhiên, mặc dù toàn bộ khung hình video vẫn hiển thị, một số phần màn hình có thể bị trống. Tuỳ thuộc vào loại tỷ lệ mà bạn chọn trong số 3 loại này, khung hình video sẽ được căn chỉnh với phần giữa, đầu hoặc cuối của View đích.

  • FILL_CENTER, FILL_START, FILL_END cho trường hợp cắt. Nếu video không khớp với tỷ lệ khung hình PreviewView, thì chỉ một phần nội dung hiển thị, nhưng video sẽ lấp đầy toàn bộ PreviewView.

Loại tỷ lệ mặc định mà CameraX sử dụng là FILL_CENTER. Hãy dùng PreviewView.setScaleType() để đặt loại tỷ lệ phù hợp nhất với ứng dụng của bạn. Mã mẫu sau đây đặt loại tỷ lệ FIT_CENTER:

Kotlin

// viewFinder is a PreviewView instance
viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER

Quy trình hiển thị video bao gồm các bước sau:

  1. Điều chỉnh video theo tỷ lệ:
    • Đối với các loại tỷ lệ FIT_*, hãy điều chỉnh video theo tỷ lệ bằng min(dst.width/src.width, dst.height/src.height).
    • Đối với các loại tỷ lệ FILL_*, hãy điều chỉnh video theo tỷ lệ bằng max(dst.width/src.width, dst.height/src.height).
  2. Căn chỉnh video được điều chỉnh theo tỷ lệ với PreviewView đích:
    • Đối với FIT_CENTER/FILL_CENTER, hãy căn giữa video được điều chỉnh theo tỷ lệ và PreviewView đích.
    • Đối với FIT_START/FILL_START, hãy căn chỉnh video được điều chỉnh theo tỷ lệ và PreviewView đích với góc trên cùng bên trái của từng cửa sổ.
    • Đối với FIT_END/FILL_END, hãy căn chỉnh video được điều chỉnh theo tỷ lệ và PreviewView đích với góc dưới cùng bên phải của từng cửa sổ.

Ví dụ: dưới đây là video nguồn 640x480 và PreviewView đích 1920x1080:

Hình ảnh minh hoạ video 640x480 so với bản xem trước 1920x1080

Hình ảnh sau đây minh hoạ quy trình điều chỉnh theo tỷ lệ FIT_START/FIT_CENTER/FIT_END:

Hình ảnh minh hoạ quy trình điều chỉnh theo tỷ lệ FIT_START, FIT_CENTER và FIT_END

Quy trình này diễn ra như sau:

  1. Điều chỉnh khung hình video theo tỷ lệ (duy trì tỷ lệ khung hình gốc) bằng min(1920/640, 1080/480) = 2.25 để có được khung hình video trung gian 1440x1080.
  2. Căn chỉnh khung hình video 1440x1080 với PreviewView 1920x1080.
    • Đối với FIT_CENTER, hãy căn chỉnh khung hình video với phần giữa của cửa sổ PreviewView. 240 cột điểm ảnh đầu và cuối của PreviewView bị trống.
    • Đối với FIT_START, hãy căn chỉnh khung hình video với phần đầu (góc trên cùng bên trái) của cửa sổ PreviewView. 480 cột điểm ảnh cuối của PreviewView bị trống.
    • Đối với FIT_END, hãy căn chỉnh khung hình video với phần cuối (góc dưới cùng bên phải) của cửa sổ PreviewView. 480 cột điểm ảnh đầu của PreviewView bị trống.

Hình ảnh sau đây minh hoạ quy trình điều chỉnh theo tỷ lệ FILL_START/FILL_CENTER/FILL_END:

Hình ảnh minh hoạ quy trình điều chỉnh theo tỷ lệ FILL_START, FILL_CENTER và FILL_END

Quy trình này diễn ra như sau:

  1. Điều chỉnh khung hình video theo tỷ lệ bằng max(1920/640, 1080/480) = 3 để có được khung hình video trung gian 1920x1440 (lớn hơn kích thước của PreviewView).
  2. Cắt khung hình video 1920x1440 cho vừa với cửa sổ PreviewView 1920x1080.
    • Đối với FILL_CENTER, hãy cắt khung hình video 1920x1080 từ phần giữa của video được điều chỉnh theo tỷ lệ 1920x1440. 180 dòng video trên cùng và dưới cùng không hiển thị.
    • Đối với FILL_START, hãy cắt khung hình video 1920x1080 từ phần đầu của video được điều chỉnh theo tỷ lệ 1920x1440. Các dòng video 360 dưới cùng không hiển thị.
    • Đối với FILL_END, hãy cắt khung hình video 1920x1080 từ phần cuối của video được điều chỉnh theo tỷ lệ 1920x1440. 360 dòng video trên cùng không hiển thị.

Tài nguyên khác

Để tìm hiểu thêm về CameraX, hãy xem các tài nguyên bổ sung sau đây.

Lớp học lập trình

  • Bắt đầu sử dụng CameraX
  • Mã mẫu

  • Ứng dụng mẫu CameraX