Khi thêm một bản xem trước vào ứng dụng của bạn, 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:
- Định cấu hình
CameraXConfig.Provider(không bắt buộc). - Thêm
PreviewViewvào bố cục. - Yêu cầu
ProcessCameraProvider. - Khi tạo
View, hãy kiểm tra xem cóProcessCameraProviderhay không. - 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ênTextureViewvàPreview.SurfaceProvider. - Truy xuất
SurfaceTexturetừTextureViewvà đặt trênPreview.SurfaceProvider. - Lấy giá trị
SurfacetừSurfaceViewvà đặt choPreview.SurfaceProvider.
Nếu bất kỳ điều nào ở trên xảy ra, 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:
- Tạo
Preview. - Chỉ định tuỳ chọn
LensFacingcho máy ảnh mà bạn muốn dùng. - Liên kết máy ảnh đã chọn và mọi trường hợp sử dụng với vòng đời.
- Kết nối
PreviewvớiPreviewView.
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); }
Xin lưu ý rằng bindToLifecycle() trả về đối tượng Camera. Để 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, hãy xem phần Đầu ra của máy ảnh.
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 để kết xuất luồng xem trước.
- Loại tỷ lệ của hình ảnh xem trước.
Chế độ triển khai
PreviewView có thể dùng một trong các chế độ sau để kết xuất luồng xem trước trên View đích:
PERFORMANCElà chế độ mặc định.PreviewViewdùngSurfaceViewđể hiển thị luồng video, nhưng sẽ quay lại dùngTextureViewtrong một số trường hợp nhất định.SurfaceViewcó 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,PreviewViewdùngTextureView(khác vớiSurfaceView) 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ị. Tại bước bổ sung này, ứng dụng có thể xử lý thêm các bước mà không bị hạn chế, ví dụ: điều chỉnh tỷ lệ và xoay video.
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ì đoạn 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ệ
Nếu độ 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 phải vừa với thành phần hiển thị bằng cách cắt hoặc dùng hiệu ứng hòm thư (giữ nguyên tỷ lệ khung hình). Để phục vụ cho việc này, PreviewView cung cấp ScaleTypes sau:
FIT_CENTER,FIT_STARTvàFIT_ENDdùng cho hiệu ứng hòm thư. 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ị trongPreviewViewđí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 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_ENDdùng khi cắt. Nếu video không khớp với tỷ lệ khung hìnhPreviewView, thì dù chỉ một phần nội dung được hiển thị, video vẫn 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. Đoạ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:
- Đ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ằngmin(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ằngmax(dst.width/src.width, dst.height/src.height).
- Đối với các loại tỷ lệ
- Căn chỉnh video được điều chỉnh theo tỷ lệ với
PreviewViewđích:FIT_CENTER/FILL_CENTER: video được điều chỉnh theo tỷ lệ sẽ được căn giữaPreviewViewđích.FIT_START/FILL_START: video được điều chỉnh theo tỷ lệ sẽ được căn chỉnh về phía góc trên cùng bên trái củaPreviewViewđích.FIT_END/FILL_END: video được điều chỉnh theo tỷ lệ sẽ được căn chỉnh về phía góc dưới cùng bên phải củaPreviewViewđích.
Ví dụ: dưới đây là video gốc có kích thước 640x480 với PreviewView đích có kích thước 1920x1080:

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

Quy trình này diễn ra như sau:
- Đ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. - Căn chỉnh khung hình video có kích thước 1440x1080 với
PreviewViewcó kích thước 1920x1080.FIT_CENTER: khung hình video sẽ được căn giữa cửa sổPreviewView. Cột 240 điểm ảnh đầu và cuối củaPreviewViewđược để trống.FIT_START: khung hình video sẽ được căn tại phần đầu (góc trên cùng bên trái) của cửa sổPreviewView. Cột 480 điểm ảnh ở phần cuối củaPreviewViewđược để trống.FIT_END: khung hình video sẽ được căn tại phần cuối (góc dưới cùng bên phải) của cửa sổPreviewView. Cột 480 điểm ảnh ở phần đầu củaPreviewViewbị trống.
Hình ảnh sau đây minh hoạ cách FILL_START/FILL_CENTER/FILL_END điều chỉnh theo tỷ lệ:

Quy trình này diễn ra như sau:
- Điều chỉnh khung hình video theo tỷ lệ với
max(1920/640, 1080/480) = 3để có được khung hình video trung gian có kích thước 1920x1440 (lớn hơn kích thước củaPreviewView). - Cắt khung hình video có kích thước 1920x1440 cho vừa với cửa sổ
PreviewViewcó kích thước 1920x1080.FILL_CENTER: khung hình video có kích thước 1920x1080 sẽ cắt từ phần giữa của video được điều chỉnh theo tỷ lệ 1920x1440. 180 dòng trên cùng và dưới cùng của video không hiển thị.FILL_START: khung hình video có kích thước 1920x1080 sẽ cắt từ phần đầu của video được điều chỉnh theo tỷ lệ 1920x1440. 360 dòng dưới cùng của video không hiển thị.FILL_END: khung hình video có kích thước 1920x1080 sẽ cắt từ phần cuối của video được điều chỉnh theo tỷ lệ 1920x1440. 360 dòng trên cùng của video 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
Đoạn mã mẫu