Lưu ý: Trang này đề cập đến gói Camera2. Bạn nên sử dụng CameraX, trừ phi ứng dụng của bạn yêu cầu các tính năng cụ thể, cấp thấp của Camera2. Cả CameraX và Camera2 đều hỗ trợ Android 5.0 (API cấp 21) trở lên.
Không phải lúc nào máy ảnh và bản xem trước của máy ảnh cũng có cùng hướng trên thiết bị Android.
Máy ảnh nằm ở một vị trí cố định trên thiết bị, bất kể thiết bị đó là điện thoại, máy tính bảng hay máy tính. Khi hướng thiết bị thay đổi, hướng camera cũng thay đổi.
Do đó, các ứng dụng máy ảnh thường giả định mối quan hệ cố định giữa hướng của thiết bị và tỷ lệ khung hình của bản xem trước máy ảnh. Khi điện thoại ở hướng dọc, bản xem trước của máy ảnh được giả định là có chiều cao lớn hơn chiều rộng. Khi điện thoại (và máy ảnh) được xoay sang ngang, bản xem trước của máy ảnh sẽ có chiều rộng lớn hơn chiều cao.
Tuy nhiên, những giả định này đang bị thách thức bởi các kiểu dáng mới, chẳng hạn như thiết bị có thể gập lại và các chế độ hiển thị như nhiều cửa sổ và nhiều màn hình. Thiết bị gập thay đổi kích thước hiển thị và tỷ lệ khung hình mà không thay đổi hướng. Chế độ nhiều cửa sổ giới hạn các ứng dụng máy ảnh ở một phần màn hình, điều chỉnh tỷ lệ bản xem trước của máy ảnh bất kể hướng thiết bị. Chế độ nhiều màn hình cho phép sử dụng màn hình phụ có thể không cùng hướng với màn hình chính.
Hướng máy ảnh
Định nghĩa về khả năng tương thích với Android chỉ rõ rằng cảm biến hình ảnh của máy ảnh "PHẢI được định hướng để chiều dài của máy ảnh phù hợp với chiều dài của màn hình". Tức là khi thiết bị được giữ theo hướng ngang, máy ảnh PHẢI chụp ảnh theo hướng ngang. Điều này áp dụng bất kể hướng tự nhiên của thiết bị; tức là áp dụng cho cả thiết bị có hướng chính là ngang và thiết bị có hướng chính là dọc."
Cách sắp xếp camera theo màn hình giúp tối đa hoá vùng hiển thị của kính ngắm camera trong ứng dụng camera. Ngoài ra, cảm biến hình ảnh thường xuất dữ liệu theo tỷ lệ khung hình ngang, trong đó 4:3 là tỷ lệ phổ biến nhất.
Hướng tự nhiên của cảm biến máy ảnh là hướng ngang. Trong hình 1, cảm biến của máy ảnh trước (máy ảnh hướng về cùng một hướng với màn hình) được xoay 270 độ so với điện thoại để tuân thủ Định nghĩa về khả năng tương thích với Android.
Để hiển thị chế độ xoay cảm biến cho các ứng dụng, API camera2 bao gồm một hằng số SENSOR_ORIENTATION. Đối với hầu hết điện thoại và máy tính bảng, thiết bị sẽ báo cáo hướng cảm biến là 270 độ cho camera trước và 90 độ (góc nhìn từ phía sau thiết bị) cho camera sau, giúp căn chỉnh cạnh dài của cảm biến với cạnh dài của thiết bị. Máy ảnh của máy tính xách tay thường báo cáo hướng cảm biến là 0 hoặc 180 độ.
Vì cảm biến hình ảnh của máy ảnh xuất dữ liệu (vùng đệm hình ảnh) theo hướng tự nhiên của cảm biến (ngang), nên vùng đệm hình ảnh phải được xoay theo số độ do SENSOR_ORIENTATION chỉ định để bản xem trước của máy ảnh xuất hiện theo hướng thẳng đứng trong hướng tự nhiên của thiết bị. Đối với camera trước,
góc xoay là ngược chiều kim đồng hồ; đối với camera sau, góc xoay là theo chiều kim đồng hồ.
Ví dụ: đối với camera trước trong hình 1, vùng đệm hình ảnh do cảm biến camera tạo ra sẽ có dạng như sau:
Bạn phải xoay hình ảnh 270 độ ngược chiều kim đồng hồ để hướng của bản xem trước khớp với hướng của thiết bị:
Camera sau sẽ tạo ra một vùng đệm hình ảnh có cùng hướng với vùng đệm trước đó, nhưng SENSOR_ORIENTATION là 90 độ. Do đó, vùng đệm được xoay 90 độ theo chiều kim đồng hồ.
Xoay thiết bị
Độ xoay thiết bị là số độ mà thiết bị được xoay so với hướng tự nhiên. Ví dụ: điện thoại theo hướng ngang có góc xoay thiết bị là 90 hoặc 270 độ, tuỳ thuộc vào hướng xoay.
Bộ đệm hình ảnh của cảm biến máy ảnh phải được xoay cùng số độ với độ xoay của thiết bị (ngoài số độ của hướng cảm biến) để bản xem trước của máy ảnh xuất hiện theo chiều thẳng đứng.
Tính toán hướng
Hướng thích hợp của bản xem trước máy ảnh sẽ xem xét hướng cảm biến và độ xoay thiết bị.
Bạn có thể tính toán độ xoay tổng thể của vùng đệm hình ảnh cảm biến bằng công thức sau:
rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360
trong đó sign là 1 đối với camera trước, -1 đối với camera sau.
Đối với camera trước, vùng đệm hình ảnh được xoay ngược chiều kim đồng hồ (từ hướng tự nhiên của cảm biến). Đối với camera sau, vùng đệm hình ảnh của cảm biến sẽ được xoay theo chiều kim đồng hồ.
Biểu thức deviceOrientationDegrees * sign + 360 chuyển đổi góc xoay của thiết bị từ ngược chiều kim đồng hồ sang theo chiều kim đồng hồ cho camera sau (ví dụ: chuyển đổi 270 độ ngược chiều kim đồng hồ thành 90 độ theo chiều kim đồng hồ). Phép toán modulo điều chỉnh kết quả thành dưới 360 độ (ví dụ: điều chỉnh góc xoay 540 độ thành 180 độ).
Các API khác nhau báo cáo chế độ xoay thiết bị theo cách khác nhau:
Display#getRotation()cung cấp góc xoay ngược chiều kim đồng hồ của thiết bị (theo góc nhìn của người dùng). Giá trị này được đưa vào công thức trước đó.OrientationEventListener#onOrientationChanged()trả về góc xoay theo chiều kim đồng hồ của thiết bị (theo góc nhìn của người dùng). Phủ định giá trị để sử dụng trong công thức trước đó.
Camera trước
Dưới đây là vùng đệm hình ảnh do cảm biến máy ảnh tạo ra trong hình 4:
Vùng đệm phải được xoay 270 độ ngược chiều kim đồng hồ để điều chỉnh theo hướng cảm biến (xem phần Hướng máy ảnh ở trên):
Sau đó, vùng đệm được xoay thêm 90 độ ngược chiều kim đồng hồ để tính đến việc xoay thiết bị, dẫn đến hướng chính xác của bản xem trước máy ảnh trong hình 4:
Dưới đây là camera được xoay sang phải theo hướng ngang:
Sau đây là vùng đệm hình ảnh:
Vùng đệm phải được xoay 270 độ ngược chiều kim đồng hồ để điều chỉnh theo hướng cảm biến:
Sau đó, vùng đệm được xoay thêm 270 độ ngược chiều kim đồng hồ để tính đến việc xoay thiết bị:
Camera sau
Máy ảnh mặt sau thường có hướng cảm biến là 90 độ (khi nhìn từ mặt sau của thiết bị). Khi định hướng bản xem trước của máy ảnh, vùng đệm hình ảnh cảm biến sẽ được xoay theo chiều kim đồng hồ theo mức độ xoay cảm biến (thay vì ngược chiều kim đồng hồ như máy ảnh trước), sau đó vùng đệm hình ảnh sẽ được xoay ngược chiều kim đồng hồ theo mức độ xoay thiết bị.
Dưới đây là vùng đệm hình ảnh từ cảm biến camera trong hình 12:
Bạn phải xoay vùng đệm 90 độ theo chiều kim đồng hồ để điều chỉnh hướng cảm biến:
Sau đó, vùng đệm được xoay 270 độ ngược chiều kim đồng hồ để tính đến chế độ xoay thiết bị:
Tỷ lệ khung hình
Tỷ lệ khung hình hiển thị thay đổi khi hướng thiết bị thay đổi, nhưng cũng thay đổi khi thiết bị có thể gập lại gập và mở, khi cửa sổ được đổi kích thước trong môi trường nhiều cửa sổ và khi ứng dụng mở trên màn hình phụ.
Vùng đệm hình ảnh của cảm biến máy ảnh phải được định hướng và điều chỉnh tỷ lệ cho phù hợp với hướng và tỷ lệ khung hình của phần tử giao diện người dùng của kính ngắm khi giao diện người dùng thay đổi hướng một cách linh động, bất kể thiết bị có thay đổi hướng hay không.
Trên các kiểu dáng mới hoặc trong môi trường nhiều cửa sổ hoặc nhiều màn hình, nếu ứng dụng của bạn giả định rằng bản xem trước của máy ảnh có cùng hướng với thiết bị (dọc hoặc ngang), thì bản xem trước có thể bị định hướng không chính xác, điều chỉnh tỷ lệ không chính xác hoặc cả hai.
Trong hình 16, ứng dụng giả định nhầm rằng thiết bị đã xoay 90 độ ngược chiều kim đồng hồ; do đó, ứng dụng đã xoay bản xem trước theo cùng một góc.
Trong hình 17, ứng dụng không điều chỉnh tỷ lệ khung hình của vùng đệm hình ảnh để cho phép ứng dụng điều chỉnh tỷ lệ cho phù hợp với kích thước mới của phần tử giao diện người dùng xem trước của máy ảnh.
Các ứng dụng máy ảnh có hướng cố định thường gặp vấn đề trên thiết bị có thể gập lại và các thiết bị màn hình lớn khác như máy tính xách tay:
Trong hình 18, giao diện người dùng của ứng dụng máy ảnh nằm ngang vì hướng của ứng dụng bị hạn chế chỉ ở chế độ dọc. Hình ảnh trong kính ngắm được định hướng chính xác so với cảm biến của camera.
Chế độ chân dung lồng ghép
Các ứng dụng máy ảnh không hỗ trợ chế độ nhiều cửa sổ (resizeableActivity="false") và hạn chế hướng (screenOrientation="portrait" hoặc screenOrientation="landscape") có thể được đặt ở chế độ chân dung lồng ghép trên các thiết bị màn hình lớn để định hướng đúng bản xem trước của máy ảnh.
Chế độ lồng ghép dọc sẽ lồng ghép (lồng ghép) các ứng dụng chỉ hiển thị theo chiều dọc theo hướng dọc, ngay cả khi tỷ lệ khung hình của màn hình là ngang. Ứng dụng chỉ hiển thị theo hướng ngang có dạng hòm thư theo hướng ngang mặc dù tỷ lệ khung hình hiển thị là dọc. Hình ảnh của máy ảnh được xoay để căn chỉnh với giao diện người dùng của ứng dụng, được cắt để khớp với tỷ lệ khung hình của bản xem trước máy ảnh, sau đó được điều chỉnh theo tỷ lệ để lấp đầy bản xem trước.
Chế độ chân dung lồng ghép được kích hoạt khi tỷ lệ khung hình của cảm biến hình ảnh máy ảnh và tỷ lệ khung hình của hoạt động chính trong ứng dụng không khớp nhau.
Trong hình 19, ứng dụng máy ảnh chỉ hỗ trợ chế độ dọc đã được xoay để hiển thị giao diện người dùng theo chiều dọc trên màn hình máy tính xách tay. Ứng dụng được tạo hiệu ứng hòm thư do sự khác biệt về tỷ lệ khung hình giữa ứng dụng dọc và màn hình ngang. Hình ảnh xem trước của máy ảnh đã được xoay để bù cho việc xoay giao diện người dùng của ứng dụng (do chế độ chân dung lồng ghép) và hình ảnh đã được cắt và điều chỉnh theo tỷ lệ để vừa với hướng dọc, làm giảm trường nhìn.
Xoay, cắt, điều chỉnh tỷ lệ
Chế độ chân dung lồng được gọi cho một ứng dụng máy ảnh chỉ hiển thị theo hướng dọc trên màn hình có tỷ lệ khung hình ngang:
Ứng dụng có dạng hòm thư theo hướng dọc:
Hình ảnh camera được xoay 90 độ để điều chỉnh theo hướng mới của ứng dụng:
Hình ảnh được cắt theo tỷ lệ khung hình của bản xem trước máy ảnh, sau đó được điều chỉnh theo tỷ lệ để lấp đầy bản xem trước (trường nhìn bị giảm):
Trên thiết bị có thể gập lại, hướng của cảm biến máy ảnh có thể là hướng dọc trong khi tỷ lệ khung hình của màn hình là hướng ngang:
Vì bản xem trước của máy ảnh được xoay để điều chỉnh theo hướng cảm biến, nên hình ảnh được định hướng đúng cách trong kính ngắm, nhưng ứng dụng chỉ hiển thị theo hướng dọc lại nằm ngang.
Chế độ chân dung lồng ghép chỉ cần hiển thị ứng dụng ở dạng hòm thư theo hướng dọc để định hướng đúng cách cho ứng dụng và bản xem trước của máy ảnh:
API
Kể từ Android 12 (API cấp 31), các ứng dụng cũng có thể kiểm soát rõ ràng chế độ chân dung lồng ghép bằng thuộc tính SCALER_ROTATE_AND_CROP của lớp CaptureRequest.
Giá trị mặc định là SCALER_ROTATE_AND_CROP_AUTO, cho phép hệ thống gọi chế độ chân dung lồng ghép.
SCALER_ROTATE_AND_CROP_90 là hành vi của chế độ chân dung lồng ghép như mô tả ở trên.
Không phải thiết bị nào cũng hỗ trợ tất cả giá trị SCALER_ROTATE_AND_CROP. Để xem danh sách các giá trị được hỗ trợ, hãy tham khảo CameraCharacteristics#SCALER_AVAILABLE_ROTATE_AND_CROP_MODES.
CameraX
Thư viện Jetpack CameraX giúp bạn dễ dàng tạo một kính ngắm máy ảnh phù hợp với hướng cảm biến và chế độ xoay thiết bị.
Phần tử bố cục PreviewView tạo bản xem trước của máy ảnh, tự động điều chỉnh theo hướng cảm biến, chế độ xoay thiết bị và tỷ lệ.
PreviewView duy trì tỷ lệ khung hình của hình ảnh camera bằng cách áp dụng loại tỷ lệ FILL_CENTER. Loại tỷ lệ này căn giữa hình ảnh nhưng có thể cắt hình ảnh để phù hợp với kích thước của PreviewView. Để tạo hiệu ứng hòm thư cho hình ảnh camera, hãy đặt loại tỷ lệ thành FIT_CENTER.
Để tìm hiểu kiến thức cơ bản về cách tạo bản xem trước của camera bằng PreviewView, hãy xem phần Triển khai bản xem trước.
Để xem cách triển khai mẫu hoàn chỉnh, hãy xem kho lưu trữ CameraXBasic trên GitHub.
CameraViewfinder
Tương tự như trường hợp sử dụng Preview, thư viện CameraViewfinder cung cấp một bộ công cụ để đơn giản hoá việc tạo bản xem trước của camera. Thư viện này không phụ thuộc vào CameraX Core, nên bạn có thể tích hợp liền mạch vào toàn bộ mã nguồn Camera2 hiện có.
Thay vì sử dụng trực tiếp Surface, bạn có thể dùng tiện ích CameraViewfinder để hiển thị nguồn cấp dữ liệu từ camera cho Camera2.
CameraViewfinder sử dụng nội bộ TextureView hoặc SurfaceView để hiển thị nguồn cấp dữ liệu từ camera và áp dụng các phép biến đổi cần thiết trên đó để hiển thị chính xác kính ngắm. Điều này bao gồm việc điều chỉnh tỷ lệ khung hình,
tỷ lệ và chế độ xoay.
Để yêu cầu nền tảng từ đối tượng CameraViewfinder, bạn cần tạo một ViewfinderSurfaceRequest.
Yêu cầu này chứa các yêu cầu về độ phân giải của nền tảng và thông tin về thiết bị camera từ CameraCharacteristics.
Việc gọi requestSurfaceAsync() sẽ gửi yêu cầu đến nhà cung cấp nền tảng (TextureView hoặc SurfaceView) và nhận được ListenableFuture của Surface.
Việc gọi markSurfaceSafeToRelease() sẽ thông báo cho nhà cung cấp nền tảng rằng nền tảng đó không cần thiết và các tài nguyên có liên quan có thể được giải phóng.
fun startCamera() {
val previewResolution = Size(width, height)
val viewfinderSurfaceRequest =
ViewfinderSurfaceRequest(previewResolution, characteristics)
val surfaceListenableFuture =
cameraViewfinder.requestSurfaceAsync(viewfinderSurfaceRequest)
Futures.addCallback(surfaceListenableFuture, object : FutureCallback<Surface> {
override fun onSuccess(surface: Surface) {
/* create a CaptureSession using this surface as usual */
}
override fun onFailure(t: Throwable) { /* something went wrong */ }
}, ContextCompat.getMainExecutor(context))
}
SurfaceView
SurfaceView là một phương pháp đơn giản để tạo bản xem trước của máy ảnh nếu bản xem trước không cần xử lý và không có ảnh động.
SurfaceView tự động xoay vùng đệm hình ảnh của cảm biến máy ảnh để khớp với hướng màn hình, tính đến cả hướng cảm biến và độ xoay thiết bị.
Tuy nhiên, vùng đệm hình ảnh được điều chỉnh theo tỷ lệ để vừa với kích thước SurfaceView mà không cần xem xét tỷ lệ khung hình.
Bạn phải đảm bảo rằng tỷ lệ khung hình của vùng đệm hình ảnh khớp với tỷ lệ khung hình của SurfaceView. Bạn có thể thực hiện việc này bằng cách điều chỉnh tỷ lệ nội dung của SurfaceView trong phương thức onMeasure() của thành phần:
(Mã nguồn computeRelativeRotation() nằm trong phần Xoay tương đối bên dưới.)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { val width = MeasureSpec.getSize(widthMeasureSpec) val height = MeasureSpec.getSize(heightMeasureSpec) val relativeRotation = computeRelativeRotation(characteristics, surfaceRotationDegrees) if (previewWidth > 0f && previewHeight > 0f) { /* Scale factor required to scale the preview to its original size on the x-axis. */ val scaleX = if (relativeRotation % 180 == 0) { width.toFloat() / previewWidth } else { width.toFloat() / previewHeight } /* Scale factor required to scale the preview to its original size on the y-axis. */ val scaleY = if (relativeRotation % 180 == 0) { height.toFloat() / previewHeight } else { height.toFloat() / previewWidth } /* Scale factor required to fit the preview to the SurfaceView size. */ val finalScale = min(scaleX, scaleY) setScaleX(1 / scaleX * finalScale) setScaleY(1 / scaleY * finalScale) } setMeasuredDimension(width, height) }
Để biết thêm thông tin chi tiết về cách triển khai SurfaceView dưới dạng bản xem trước của máy ảnh, hãy xem bài viết Hướng máy ảnh.
TextureView
TextureView có hiệu suất thấp hơn SurfaceView và cần nhiều thao tác hơn, nhưng TextureView cho phép bạn kiểm soát tối đa bản xem trước của máy ảnh.
TextureView xoay vùng đệm hình ảnh của cảm biến dựa trên hướng cảm biến nhưng không xử lý việc xoay thiết bị hoặc điều chỉnh tỷ lệ xem trước.
Bạn có thể mã hoá việc điều chỉnh tỷ lệ và xoay trong phép biến đổi Matrix.
Để tìm hiểu cách điều chỉnh tỷ lệ và xoay TextureView một cách chính xác, hãy xem bài viết Hỗ trợ các nền tảng có thể đổi kích thước trong ứng dụng camera.
Xoay tương đối
Độ xoay tương đối của cảm biến máy ảnh là mức độ xoay cần thiết để căn chỉnh đầu ra của cảm biến máy ảnh theo hướng của thiết bị.
Các thành phần như SurfaceView và TextureView sử dụng chế độ xoay tương đối để xác định hệ số tỷ lệ x và y cho hình ảnh xem trước. Trường này cũng được dùng để chỉ định chế độ xoay của vùng đệm hình ảnh cảm biến.
Các lớp CameraCharacteristics và Surface cho phép tính toán chế độ xoay tương đối của cảm biến máy ảnh:
/** * Computes rotation required to transform the camera sensor output orientation to the * device's current orientation in degrees. * * @param characteristics The CameraCharacteristics to query for the sensor orientation. * @param surfaceRotationDegrees The current device orientation as a Surface constant. * @return Relative rotation of the camera sensor output. */ public fun computeRelativeRotation( characteristics: CameraCharacteristics, surfaceRotationDegrees: Int ): Int { val sensorOrientationDegrees = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) ?: 0 // Reverse device orientation for back-facing cameras. val sign = if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT ) 1 else -1 // Calculate desired orientation relative to camera orientation to make // the image upright relative to the device orientation. return (sensorOrientationDegrees - surfaceRotationDegrees * sign + 360) % 360 }
Chỉ số cửa sổ
Bạn không nên dùng kích thước màn hình để xác định kích thước của kính ngắm máy ảnh; ứng dụng máy ảnh có thể đang chạy trong một phần màn hình, ở chế độ nhiều cửa sổ trên thiết bị di động hoặc chế độ dạng thức tuỳ ý trên ChromeOS.
WindowManager#getCurrentWindowMetrics() (được thêm vào cấp độ API 30) trả về kích thước của cửa sổ ứng dụng thay vì kích thước của màn hình. Các phương thức WindowMetricsCalculator#computeCurrentWindowMetrics() và WindowInfoTracker#currentWindowMetrics() trong thư viện WindowManager của Jetpack cung cấp chức năng hỗ trợ tương tự nhưng có khả năng tương thích ngược với cấp độ API 14.
xoay 180 độ
Việc xoay thiết bị 180 độ (ví dụ: từ hướng tự nhiên sang hướng tự nhiên lộn ngược) không kích hoạt lệnh gọi lại onConfigurationChanged(). Do đó, bản xem trước của máy ảnh có thể bị lộn ngược.
Để phát hiện góc xoay 180 độ, hãy triển khai DisplayListener và kiểm tra góc xoay của thiết bị bằng lệnh gọi đến Display#getRotation() trong lệnh gọi lại onDisplayChanged().
Tài nguyên độc quyền
Trước Android 10, chỉ hoạt động hiển thị trên cùng trong môi trường nhiều cửa sổ mới ở trạng thái RESUMED. Điều này gây nhầm lẫn cho người dùng vì hệ thống không cho biết hoạt động nào đã được tiếp tục.
Android 10 (cấp độ API 29) ra mắt tính năng tiếp tục nhiều lần, trong đó tất cả hoạt động hiển thị đều ở trạng thái RESUMED. Các hoạt động hiển thị vẫn có thể chuyển sang trạng thái PAUSED nếu, ví dụ: một hoạt động minh bạch nằm trên hoạt động đó hoặc khi không thể lấy hoạt động đó làm tâm điểm, chẳng hạn như ở chế độ hình trong hình (xem phần Hỗ trợ chế độ hình trong hình).
Ứng dụng sử dụng máy ảnh, micrô hoặc bất kỳ tài nguyên độc quyền hay singleton nào trên cấp độ API 29 trở lên đều phải hỗ trợ chế độ tiếp tục nhiều lần. Ví dụ: nếu ba hoạt động được tiếp tục muốn sử dụng máy ảnh, thì chỉ một hoạt động có thể truy cập vào tài nguyên độc quyền này. Mỗi hoạt động phải triển khai một lệnh gọi lại onDisconnected() để luôn nhận biết được quyền truy cập ưu tiên vào máy ảnh của một hoạt động có mức độ ưu tiên cao hơn.
Để biết thêm thông tin, hãy xem phần Tiếp tục nhiều hoạt động.
Tài nguyên khác
- Để xem mẫu Camera2, hãy xem ứng dụng Camera2Basic trên GitHub.
- Để tìm hiểu về trường hợp sử dụng bản xem trước CameraX, hãy xem bài viết Triển khai bản xem trước của CameraX.
- Để biết cách triển khai mẫu xem trước máy ảnh CameraX, hãy xem kho lưu trữ CameraXBasic trên GitHub.
- Để biết thông tin về bản xem trước của máy ảnh trên ChromeOS, hãy xem phần Hướng máy ảnh.
- Để biết thông tin về cách phát triển cho thiết bị có thể gập lại, hãy xem bài viết Tìm hiểu về thiết bị có thể gập lại.