Tiện ích Camera

Nhà sản xuất thiết bị có thể để lộ các tiện ích như hiệu ứng bokeh, chế độ ban đêm và HDR tới nhà phát triển bên thứ ba thông qua giao diện Tiện ích máy ảnh được cung cấp bởi thư viện nhà cung cấp OEM. Nhà phát triển có thể sử dụng Camera2 Extensions APICameraX Extensions API để truy cập vào các tiện ích được triển khai trong thư viện nhà cung cấp OEM.

Danh sách các tiện ích được hỗ trợ tương tự như trên Camera2 và CameraX, hãy xem CameraX Extensions API. Nếu muốn thêm một tiện ích, báo cáo lỗi bằng Công cụ theo dõi lỗi.

Trang này mô tả cách triển khai và bật thư viện nhà cung cấp OEM trên thiết bị.

Kiến trúc

Biểu đồ sau đây mô tả cấu trúc của Tiện ích Máy ảnh giao diện hoặc extensions-interface: Kiến trúc

Hình 1. Sơ đồ cấu trúc của các tiện ích Máy ảnh

Như minh hoạ trong sơ đồ, để hỗ trợ Tiện ích máy ảnh, bạn cần triển khai extensions-interface do thư viện nhà cung cấp OEM cung cấp. Thông tin Thư viện nhà cung cấp OEM hỗ trợ 2 API: CameraX Extensions APICamera2 Extensions API được ứng dụng CameraX và Camera2 lần lượt dùng để truy cập tiện ích của nhà cung cấp.

Triển khai thư viện nhà cung cấp OEM

Để triển khai thư viện nhà cung cấp OEM, hãy sao chép camera-extensions-stub vào dự án thư viện hệ thống. Các tệp này xác định Tiện ích máy ảnh .

camera-extensions-stub tệp được chia thành các danh mục sau:

Tệp giao diện thiết yếu (đừng sửa đổi)

  • PreviewExtenderImpl.java
  • ImageCaptureExtenderImpl.java
  • ExtenderStateListener.java
  • ProcessorImpl.java
  • PreviewImageProcessorImpl.java
  • CaptureProcessorImpl.java
  • CaptureStageImpl.java
  • RequestUpdateProcessorImpl.java
  • ProcessResultImpl.java
  • advanced/AdvancedExtenderImpl.java
  • advanced/Camera2OutputConfigImpl.java
  • advanced/Camera2SessionConfigImpl.java
  • advanced/ImageProcessorImpl.java
  • advanced/ImageReaderOutputConfigImpl.java
  • advanced/ImageReferenceImpl.java
  • advanced/MultiResolutionImageReaderOutputConfigImpl.java
  • advanced/OutputSurfaceImpl.java
  • advanced/RequestProcessorImpl.java
  • advanced/SessionProcessorImpl.java
  • advanced/SurfaceOutputConfigImpl.java

Các phương pháp triển khai bắt buộc (thêm phương thức triển khai của bạn)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Lớp mở rộng hiệu ứng bokeh (triển khai lớp này nếu tiện ích Bokeh được hỗ trợ)

  • BokehImageCaptureExtenderImpl.java
  • BokehPreviewExtenderImpl.java
  • advanced/BokehAdvancedExtenderImpl.java

Các lớp mở rộng ban đêm (triển khai nếu tiện ích ban đêm được hỗ trợ)

  • NightImageCaptureExtenderImpl.java
  • NightPreviewExtenderImpl.java
  • advanced/NightAdvancedExtenderImpl.java

Các lớp trình mở rộng tự động (triển khai nếu Tiện ích tự động được hỗ trợ)

  • AutoImageCaptureExtenderImpl.java
  • AutoPreviewExtenderImpl.java
  • advanced/AutoAdvancedExtenderImpl.java

Lớp mở rộng HDR (triển khai lớp này nếu phần mở rộng HDR được hỗ trợ)

  • HdrImageCaptureExtenderImpl.java
  • HdrPreviewExtenderImpl.java
  • advanced/HdrAdvancedExtenderImpl.java

Các lớp mở rộng tính năng Làm đẹp khuôn mặt (triển khai nếu tiện ích Làm đẹp khuôn mặt được hỗ trợ)

  • BeautyImageCaptureExtenderImpl.java
  • BeautyPreviewExtenderImpl.java
  • advanced/BeautyAdvancedExtenderImpl.java

Tiện ích (không bắt buộc, có thể xoá)

  • advanced/Camera2OutputConfigImplBuilder.java
  • advanced/Camera2SessionConfigImplBuilder.java

Bạn không bắt buộc phải cung cấp phương thức triển khai cho mọi phần mở rộng. Nếu bạn không triển khai tiện ích, đặt isExtensionAvailable() để trả về false hoặc xoá các lớp Extender tương ứng. Tiện ích Camera2 và CameraX API sẽ báo cáo cho ứng dụng về việc tiện ích không hoạt động.

Hãy cùng tìm hiểu cách các API Tiện ích Camera2 và CameraX tương tác với thư viện nhà cung cấp để bật tiện ích. Biểu đồ dưới đây minh hoạ luồng hai đầu sử dụng tiện ích Ban đêm làm ví dụ:

Dòng chính

Hình 2. Triển khai tiện ích ban đêm

  1. Xác minh phiên bản:

    Camera2/X gọi ExtensionVersionImpl.checkApiVersion() để đảm bảo rằng Phiên bản extensions-interface do OEM triển khai tương thích với Camera2/X phiên bản được hỗ trợ.

  2. Khởi chạy thư viện nhà cung cấp:

    InitializerImpl có phương thức init() giúp khởi chạy thư viện nhà cung cấp. Camera2/X hoàn tất quá trình khởi chạy trước khi truy cập vào các lớp Extender.

  3. Tạo thực thể cho các lớp Extender:

    Tạo thực thể cho các lớp Extender cho tiện ích. Có 2 Bộ kéo dài các loại: Bộ mở rộng cơ bản và Bộ mở rộng nâng cao. Bạn phải triển khai một Loại trình mở rộng cho tất cả Tiện ích. Để biết thêm thông tin, hãy xem Trình mở rộng cơ bản và Trình mở rộng nâng cao.

    Camera2/X tạo thực thể và tương tác với các lớp Extender để truy xuất thông tin và bật tiện ích đó. Đối với một tiện ích cụ thể, Camera2/X có thể tạo thực thể cho các lớp Extender nhiều lần. Do đó, đừng khởi tạo tốn nhiều tài nguyên trong hàm khởi tạo hoặc lệnh gọi init(). Thực hiện công việc nặng nhọc chỉ khi phiên quay phim sắp diễn ra khởi động, chẳng hạn như khi onInit() được gọi trong Basic Extender hoặc initSession() được gọi trong Advanced Extender.

    Đối với tiện ích Night, các lớp Extender sau đây được tạo thực thể cho loại Basic Extender (Bộ mở rộng cơ bản):

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    Còn đối với loại Advanced Extender:

    • NightAdvancedExtenderImpl.java
  4. Kiểm tra phạm vi cung cấp của tiện ích:

    Trước khi bật tiện ích, isExtensionAvailable() sẽ kiểm tra xem tiện ích có sẵn trên mã nhận dạng máy ảnh được chỉ định thông qua Extender thực thể.

  5. Khởi động Extender với thông tin về máy ảnh:

    Camera2/X gọi init() trên thực thể Extender và truyền camera cho thực thể đó Mã nhận dạng và CameraCharacteristics.

  6. Thông tin về cụm từ tìm kiếm:

    Gọi lớp Extender để truy xuất thông tin như được hỗ trợ độ phân giải, vẫn ghi lại độ trễ ước tính và lấy khoá yêu cầu từ Extender để chuẩn bị bật tiện ích.

  7. Bật tiện ích trên Extender:

    Lớp Extender cung cấp tất cả các giao diện cần thiết để bật . Cung cấp cơ chế kết nối OEM vào quy trình Camera2, chẳng hạn như chèn yêu cầu chụp ảnh hoặc bật trình xử lý bài đăng.

    Đối với loại Advanced Extender, Camera2/X tương tác với SessionProcessorImpl để bật tiện ích. Camera2/X truy xuất thực thể SessionProcessorImpl bằng cách gọi createSessionProcessor() trên Thanh nối dài.

Các phần sau đây sẽ mô tả chi tiết hơn về quy trình mở rộng.

Xác minh phiên bản

Khi tải thư viện nhà cung cấp OEM từ thiết bị trong thời gian chạy, Camera2/X xác minh xem thư viện có tương thích với phiên bản extensions-interface hay không. extensions-interface sử dụng phiên bản ngữ nghĩa, hoặc MAJOR.MINOR.PATCH, ví dụ: 1.1.0 hoặc 1.2.0. Tuy nhiên, chỉ có các phiên bản chính và nhỏ sẽ được dùng trong quá trình xác minh phiên bản.

Để xác minh phiên bản, Camera2/X sẽ gọi ExtensionVersionImpl.checkApiVersion() với Phiên bản extensions-interface. Sau đó, Camera2/X sử dụng phiên bản do Thư viện OEM để xác định xem có thể bật tiện ích không và xác định những chức năng nó sẽ gọi ra.

Khả năng tương thích với phiên bản lớn

Nếu các phiên bản chính của giao diện tiện ích khác nhau giữa Camera2/X và thư viện của nhà cung cấp thì được coi là không tương thích và tiện ích đã bị tắt.

Khả năng tương thích ngược

Miễn là phiên bản chính giống hệt nhau, Camera2/X sẽ đảm bảo khả năng tương thích ngược với thư viện của nhà cung cấp OEM được tạo bằng công nghệ extensions-interface phiên bản. Ví dụ: nếu Camera2/X hỗ trợ extensions-interface 1.3.0, thư viện nhà cung cấp OEM đã triển khai phiên bản 1.0.0, 1.1.0 và 1.2.0 vẫn tương thích. Điều này cũng có nghĩa là sau khi bạn triển khai một phiên bản cụ thể của thư viện nhà cung cấp, Camera2/X đảm bảo thư viện tương thích ngược với các phiên bản extension-interface sắp tới.

Khả năng tương thích chuyển tiếp

Chuyển tiếp khả năng tương thích với thư viện nhà cung cấp của extensions-interface mới hơn tuỳ thuộc vào bạn, OEM. Nếu bạn cần một số tính năng để triển khai phần mở rộng, bạn có thể muốn bật các tiện ích mở rộng bắt đầu từ một phiên bản nhất định. Trong phần này trong trường hợp, bạn có thể trả về phiên bản extensions-interface được hỗ trợ khi Phiên bản thư viện Camera2/X đáp ứng các yêu cầu này. Nếu phiên bản Camera2/X không được hỗ trợ, bạn có thể trả về phiên bản không tương thích, chẳng hạn như 99.0.0 để tắt các tiện ích đó.

Khởi chạy thư viện nhà cung cấp

Sau khi xác minh phiên bản extensions-interface do OEM triển khai thư viện, Camera2/X sẽ bắt đầu quá trình khởi chạy. Chiến lược phát hành đĩa đơn Phương thức InitializerImpl.init() báo hiệu cho thư viện OEM biết rằng một ứng dụng đang dùng thử để sử dụng tiện ích.

Camera2/X không thực hiện lệnh gọi nào khác đến thư viện OEM (ngoài việc kiểm tra phiên bản) cho đến khi thư viện nhà cung cấp OEM gọi OnExtensionsInitializedCallback.onSuccess() để thông báo việc hoàn tất quá trình khởi chạy.

Bạn phải triển khai InitializerImpl kể từ extensions-interface 1.1.0. Camera2/X bỏ qua quá trình khởi chạy thư viện bước nếu thư viện nhà cung cấp OEM triển khai extensions-interface 1.0.0.

Trình mở rộng cơ bản so với Trình mở rộng nâng cao

Có hai cách triển khai extensions-interface: Basic Extender và Trình mở rộng nâng cao. Advanced Extender đã được hỗ trợ kể từ extensions-interface 1.2.0.

Triển khai Trình mở rộng cơ bản cho các tiện ích xử lý hình ảnh trong lớp trừu tượng phần cứng (HAL) hoặc sử dụng trình xử lý bài đăng có khả năng xử lý luồng YUV.

Triển khai Trình mở rộng nâng cao cho những tiện ích cần tuỳ chỉnh Camera2 định cấu hình luồng và gửi yêu cầu chụp nếu cần.

Hãy xem bảng sau để biết thông tin so sánh:

Thanh nối dài cơ bản Trình mở rộng nâng cao
Cấu hình luồng Cố định
Bản xem trước: PRIVATE hoặc YUV_420_888 (nếu có bộ xử lý)
Ảnh tĩnh: JPEG hoặc YUV_420_888 (nếu có bộ xử lý)
Do OEM (Nhà sản xuất thiết bị gốc) tuỳ chỉnh.
Đang gửi yêu cầu chụp ảnh Chỉ Camera2/X mới có thể gửi yêu cầu chụp. Bạn có thể đặt các thông số thành các yêu cầu này. Khi bộ xử lý được cung cấp để chụp ảnh, Camera2/X có thể gửi nhiều yêu cầu chụp cũng như gửi tất cả các hình ảnh và bản chụp kết quả cho đơn vị xử lý. Một thực thể RequestProcessorImpl được cung cấp cho bạn để thực hiện yêu cầu chụp bằng camera2 và nhận kết quả cũng như Hình ảnh.

Camera2/X gọi startRepeatingstartCapture trên SessionProcessorImpl để báo hiệu cho OEM bắt đầu lặp lại yêu cầu xem trước và bắt đầu chuỗi chụp ảnh tĩnh tương ứng.

Móc trong quy trình camera
  • onPresetSession cung cấp các tham số phiên.
  • onEnableSession sẽ gửi một yêu cầu duy nhất ngay sau khi định cấu hình CameraCaptureSession.
  • onDisableSession sẽ gửi một yêu cầu duy nhất trước khi CameraCaptureSession đóng.
  • initSession khởi chạy và trả về một camera2 tuỳ chỉnh cấu hình phiên để tạo phiên chụp.
  • onCaptureSessionStart được gọi ngay sau khi định cấu hình CameraCaptureSession.
  • onCaptureSessionEnd được gọi trước khi đóng CameraCaptureSession.
Phù hợp với Các tiện ích được triển khai trong lớp trừu tượng phần cứng (HAL) cho máy ảnh hoặc trong bộ xử lý có khả năng xử lý Hình ảnh YUV.
  • Có các cách triển khai dựa trên Camera2 cho các tiện ích.
  • Cần cấu hình luồng tuỳ chỉnh, chẳng hạn như luồng RAW.
  • Cần trình tự chụp tương tác.
Phiên bản API được hỗ trợ Tiện ích Camera2: Android 13 trở lên
Tiện ích CameraX: camera-extensions 1.1.0 trở lên
Tiện ích Camera2: Android 12L trở lên
Tiện ích CameraX: camera-extensions 1.2.0-alpha03 trở lên

Luồng ứng dụng

Bảng sau đây trình bày 3 loại luồng ứng dụng và các lệnh gọi API Tiện ích máy ảnh tương ứng. Trong khi Camera2/X cung cấp các API này, bạn phải triển khai đúng cách thư viện nhà cung cấp để hỗ trợ mà chúng tôi sẽ mô tả chi tiết hơn ở phần sau.

Tiện ích Camera2 Tiện ích CameraX
Khả năng sử dụng phần mở rộng về cụm từ tìm kiếm CameraExtensionCharacteristics .getSupportedExtensions ExtensionsManager. isExtensionAvailable
Thông tin về cụm từ tìm kiếm CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX xử lý phần thông tin còn lại trong thư viện.

Xem trước và chụp ảnh tĩnh khi bật tiện ích CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector

bindToLifecycle(lifecycleOwner, cameraSelector, preview, ...)

Thanh nối dài cơ bản

Giao diện Basic Extender (Trình mở rộng cơ bản) cung cấp các điểm kết nối vào nhiều vị trí trong máy ảnh quy trình. Mỗi loại tiện ích có các lớp Extender tương ứng mà OEM cần để triển khai.

Bảng sau đây liệt kê các lớp Extender mà OEMS cần triển khai cho mỗi lớp phần mở rộng:

Các lớp mở rộng để triển khai
Đêm NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java

HdrImageCaptureExtenderImpl.java

Ô tô AutoPreviewExtenderImpl.java

AutoImageCaptureExtenderImpl.java

Hiệu ứng bokeh BokehPreviewExtenderImpl.java

BokehImageCaptureExtenderImpl.java

Làm đẹp khuôn mặt BeautyPreviewExtenderImpl.java

BeautyImageCaptureExtenderImpl.java

Chúng tôi dùng PreviewExtenderImplImageCaptureExtenderImpl làm phần giữ chỗ trong ví dụ sau. Thay thế các tham số này bằng tên của các thực thể mà bạn đang triển khai.

Basic Extender có các chức năng sau:

  • Chèn thông số phiên khi định cấu hình CameraCaptureSession ( onPresetSession).
  • Thông báo cho bạn về các sự kiện bắt đầu và đóng phiên chụp, đồng thời gửi một sự kiện yêu cầu thông báo cho HAL (Lớp trừu tượng phần cứng) bằng các tham số được trả về (onEnableSession, onDisableSession).
  • Chèn các tham số thu thập cho yêu cầu (PreviewExtenderImpl.getCaptureStage, ImageCaptureExtenderImpl.getCaptureStages).
  • Thêm bộ xử lý để xem trước mà vẫn chụp được có khả năng xử lý Luồng YUV_420_888.

Hãy xem cách Camera2/X gọi extensions-interface để đạt được ba luồng ứng dụng nêu trên.

Luồng ứng dụng 1: Kiểm tra khả năng sử dụng tiện ích

Cơ bản ExtenderAppFlow1

Hình 3. Luồng ứng dụng 1 trên Basic Extender

Trong luồng này, Camera2/X trực tiếp gọi phương thức isExtensionAvailable() của cả PreviewExtenderImplImageCaptureExtenderImpl mà không cần gọi init(). Cả hai lớp Extender đều phải trả về true để bật tiện ích.

Đây thường là bước đầu tiên để ứng dụng kiểm tra xem tiện ích đã cho được hỗ trợ cho một mã máy ảnh nhất định trước khi bật tiện ích. Điều này là do một số tiện ích chỉ được hỗ trợ trên một số mã máy ảnh nhất định.

Luồng ứng dụng 2: Truy vấn thông tin

Cơ bản

Hình 4. Luồng ứng dụng 2 trên Basic Extender

Sau khi xác định xem tiện ích có dùng được hay không, các ứng dụng nên truy vấn thông tin sau đây trước khi bật tiện ích.

  • Vẫn ghi nhận được phạm vi độ trễ: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange trả về phạm vi độ trễ chụp để ứng dụng đánh giá xem khoảng thời gian đó có phù hợp để bật tiện ích cho trường hợp hiện tại.

  • Các kích thước được hỗ trợ cho bản xem trước và giao diện chụp: ImageCaptureExtenderImpl.getSupportedResolutionsPreviewExtenderImpl.getSupportedResolutions trả về danh sách các định dạng hình ảnh và các kích thước được hỗ trợ cho định dạng và kích thước nền tảng.

  • Các khoá kết quả và yêu cầu được hỗ trợ: Camera2/X gọi các phương thức sau để truy xuất ảnh chụp được hỗ trợ yêu cầu khoá và khoá kết quả từ quá trình triển khai của bạn:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X luôn gọi init() trước tiên trên các lớp Extender này trước khi truy vấn để biết thêm thông tin.

Quy trình ứng dụng 3: Xem trước/chụp ảnh tĩnh khi bật tiện ích (triển khai HAL)

Cơ bản ExtenderAppFlow3

Hình 5. Luồng ứng dụng 3 trên Basic Extender

Biểu đồ trên minh hoạ quy trình chính để bật tính năng xem trước mà vẫn chụp bằng một tiện ích mà không cần bất kỳ bộ xử lý nào. Điều này có nghĩa là lớp trừu tượng phần cứng (HAL) của máy ảnh xử lý tiện ích.

Trong quy trình này, Camera2/X gọi init() trước tiên, sau đó gọi onInit để thông báo cho bạn phiên camera sắp bắt đầu với các tiện ích được chỉ định. Bạn có thể thực hiện việc khởi động tốn nhiều công sức trong onInit().

Khi định cấu hình CameraCaptureSession, Camera2/X sẽ gọi onPresetSession để nhận thông số phiên. Sau phiên chụp đã định cấu hình thành công, Camera2/X gọi onEnableSession trả về một CaptureStageImpl thực thể chứa thông số thu thập. Camera2/X ngay lập tức gửi một yêu cầu duy nhất cùng với các thông số thu thập này để thông báo Lớp trừu tượng phần cứng (HAL). Tương tự, trước khi phiên chụp đóng, Camera2/X sẽ gọi onDisableSession, sau đó gửi một yêu cầu duy nhất cùng với dữ liệu chụp được trả về tham số.

Yêu cầu lặp lại do Camera2/X kích hoạt chứa các tham số yêu cầu được trả về bởi PreviewExtenderImpl.getCaptureStage(). Ngoài ra, yêu cầu chụp ảnh chứa các tham số được trả về bởi ImageCaptureExtenderImpl.getCaptureStages().

Cuối cùng, Camera2/X gọi onDeInit() sau khi phiên máy ảnh kết thúc. Bạn có thể phát hành tài nguyên trong onDeinit().

Trình xử lý bản xem trước

Ngoài lớp trừu tượng phần cứng (HAL) cho máy ảnh, bạn cũng có thể triển khai các tiện ích trong bộ xử lý.

Triển khai PreviewExtenderImpl.getProcessorType để chỉ định loại bộ xử lý như được giải thích bên dưới:

  • PROCESSOR_TYPE_NONE: Không có đơn vị xử lý. Hình ảnh được xử lý trong camera Lớp trừu tượng phần cứng (HAL).

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY: Loại bộ xử lý cho phép bạn cập nhật yêu cầu lặp lại bằng các thông số yêu cầu chụp mới dựa trên TotalCaptureResult mới nhất.

    PreviewExtenderImpl.getProcessor phải trả về một RequestUpdateProcessorImpl thực thể xử lý thực thể TotalCaptureResult và trả về một thực thể Thực thể CaptureStageImpl để cập nhật yêu cầu lặp lại. PreviewExtenderImpl.getCaptureStage() cũng phải phản ánh kết quả của quá trình xử lý và trả về CaptureStageImpl mới nhất.

  • PROCESSOR_TYPE_IMAGE_PROCESSOR: Loại này cho phép bạn triển khai một để xử lý hình ảnh YUV_420_888 và ghi đầu ra vào một Nền tảng PRIVATE.

    Bạn cần triển khai và trả về một PreviewImageProcessorImpl thực thể trong PreviewExtenderImpl.getProcessor. Đơn vị xử lý chịu trách nhiệm để xử lý YUV_420_888 hình ảnh đầu vào. Mã này sẽ ghi đầu ra vào Định dạng xem trước PRIVATE. Camera2/X sử dụng nền tảng YUV_420_888 của PRIVATE để định cấu hình CameraCaptureSession cho chế độ xem trước.

    Hãy xem hình minh hoạ sau đây cho quy trình này:

PreviewProcessor

Hình 6. Xem trước quy trình bằng PreviewImageProcessorImpl

Giao diện PreviewImageProcessorImpl mở rộng ProcessImpl và có ba phương pháp quan trọng:

  • onOutputSurface(Surface surface, int imageFormat) thiết lập giao diện đầu ra cho bộ xử lý. Đối với PreviewImageProcessorImpl, imageFormat là một pixel chẳng hạn như PixelFormat.RGBA_8888.

  • onResolutionUpdate(Size size) đặt kích thước của hình ảnh đầu vào.

  • onImageFormatUpdate(int imageFormat) đặt định dạng hình ảnh của đầu vào hình ảnh. Hiện tại, chế độ này chỉ có thể là YUV_420_888.

Trình xử lý chụp ảnh

Để chụp ảnh tĩnh, bạn có thể triển khai bộ xử lý bằng cách trả về một CaptureProcessorImpl bằng ImageCaptureExtenderImpl.getCaptureProcessor. Bộ xử lý là chịu trách nhiệm xử lý danh sách YUV_420_888 hình ảnh đã chụp và Thực thể TotalCaptureResult và ghi đầu ra vào nền tảng YUV_420_888.

Bạn có thể yên tâm giả định rằng bản xem trước được bật và chạy trước khi gửi vẫn chụp yêu cầu.

Xem quy trình trong biểu đồ dưới đây:

Bộ xử lý Capture

Hình 7. Vẫn chụp quy trình bằng CaptureProcessorImpl

  1. Camera2/X sử dụng bề mặt định dạng YUV_420_888 để chụp ảnh tĩnh nhằm định cấu hình phiên chụp. Camera2/X chuẩn bị CaptureProcessorImpl bằng cách gọi:

    • CaptureProcessorImpl.onImageFormatUpdate() cho thành viên YUV_420_888.
    • CaptureProcessorImpl.onResolutionUpdate() với kích thước hình ảnh đầu vào.
    • CaptureProcessorImpl.onOutputSurface() với giá trị đầu ra là YUV_420_888 nền tảng.
  2. ImageCaptureExtenderImpl.getCaptureStages trả về danh sách CaptureStageImpl , trong đó mỗi phần tử ánh xạ đến một thực thể CaptureRequest có các tham số thu thập do Camera2/X gửi. Ví dụ: nếu nó trả về danh sách ba CaptureStageImpl thực thể, Camera2/X gửi 3 yêu cầu chụp bằng tham số thu thập tương ứng bằng cách sử dụng captureBurst API.

  3. Các hình ảnh đã nhận và TotalCaptureResult thực thể được nhóm lại với nhau và gửi đến CaptureProcessorImpl để xử lý.

  4. CaptureProcessorImpl ghi kết quả Hình ảnh (định dạng YUV_420_888) vào bề mặt đầu ra do lệnh gọi onOutputSurface() chỉ định. Camera2/X chuyển đổi hàm này vào hình ảnh JPEG nếu cần.

Hỗ trợ kết quả và khoá yêu cầu chụp

Ngoài việc xem trước và chụp ảnh, các ứng dụng có thể đặt thu phóng, flash hoặc kích hoạt chế độ nhấn để lấy nét. Các thông số này có thể không tương thích với việc triển khai tiện ích của bạn.

Các phương thức sau đã được thêm vào extensions-interface 1.3.0 để cho phép bạn sẽ hiển thị các tham số mà quá trình triển khai của bạn hỗ trợ:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() trả về khoá yêu cầu ghi lại mà cách triển khai của bạn hỗ trợ.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() trả về chụp khoá kết quả có trong kết quả chụp.

Nếu lớp trừu tượng phần cứng (HAL) của máy ảnh xử lý tiện ích, thì Camera2/X sẽ truy xuất ảnh chụp kết quả bằng CameraCaptureSession.CaptureCallback. Tuy nhiên, nếu bộ xử lý được triển khai, sau đó Camera2/X truy xuất kết quả chụp trong ProcessResultImpl , được truyền đến process() phương thức trong PreviewImageProcessorImplCaptureProcessorImpl. Bạn có trách nhiệm báo cáo kết quả chụp thông qua ProcessResultImpl đến Camera2/X.

Hãy xem định nghĩa về giao diện CaptureProcessorImpl dưới đây làm ví dụ. Trong extensions-interface 1.3.0 trở lên, lệnh gọi process() thứ hai sẽ được gọi:

Interface CaptureProcessorImpl extends ProcessorImpl {
    // invoked when extensions-interface version < 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
    // invoked when extensions-interface version >= 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
            ProcessResultImpl resultCallback, Executor executor);
}

Đối với các thao tác phổ biến của máy ảnh như thu phóng, nhấn để lấy nét, đèn flash và độ phơi sáng nên bạn nên hỗ trợ các khoá sau để lấy cả hai và thu thập kết quả:

  • Thu phóng:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • Nhấn để lấy nét:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Quảng cáo Flash:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Bù phơi nhiễm:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

Đối với các Trình mở rộng cơ bản triển khai phiên bản 1.2.0 hoặc các phiên bản trước, CameraX Extensions API hỗ trợ tất cả các khoá nêu trên một cách rõ ràng. Cho extensions-interface 1.3.0, cả CameraX và Camera2 đều tuân thủ danh sách được trả về và chỉ hỗ trợ các khoá có trong đó. Ví dụ: nếu bạn quyết định trả lại chỉ CaptureRequest#CONTROL_ZOOM_RATIOCaptureRequest#SCALER_CROP_REGION trong lần triển khai 1.3.0, sau đó có nghĩa là chỉ hỗ trợ thu phóng cho ứng dụng trong khi nhấn để lấy nét, đèn flash và độ phơi sáng không được phép trả tiền.

Trình mở rộng nâng cao

Advanced Extender là một kiểu triển khai của nhà cung cấp dựa trên API Camera2. Loại Extender này đã được thêm vào trong extensions-interface 1.2.0. Tuỳ thuộc vào nhà sản xuất thiết bị, tiện ích có thể được triển khai trong lớp ứng dụng, tuỳ thuộc vào các yếu tố sau:

  • Cấu hình luồng tuỳ chỉnh: Định cấu hình các luồng tuỳ chỉnh như luồng RAW hoặc có nhiều luồng cho các mã máy ảnh thực khác nhau.

  • Khả năng gửi yêu cầu Camera2: Hỗ trợ một hoạt động tương tác phức tạp logic có thể gửi yêu cầu chụp với các tham số dựa trên kết quả của các yêu cầu trước đó.

Advanced Extender cung cấp một trình bao bọc hoặc một lớp trung gian để bạn có thể tuỳ chỉnh cấu hình luồng và gửi yêu cầu chụp theo yêu cầu.

Tệp để triển khai

Để chuyển sang phương thức triển khai Advanced Extender, Phương thức isAdvancedExtenderImplemented() trong ExtensionVersionImpl phải trả về true. Đối với mỗi loại tiện ích, OEM phải triển khai các lớp Extender tương ứng. Các tệp triển khai Trình mở rộng nâng cao là trong gói nâng cao.

Các lớp mở rộng cần triển khai
Đêm advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Ô tô advanced/AutoAdvancedExtenderImpl.java
Hiệu ứng bokeh advanced/BokehAdvancedExtenderImpl.java
Làm đẹp khuôn mặt advanced/BeautyAdvancedExtenderImpl.java

Chúng ta dùng AdvancedExtenderImpl làm phần giữ chỗ trong ví dụ sau. Thay thế tệp này bằng tên của tệp Extender cho tiện ích bạn đang sử dụng triển khai.

Hãy xem cách Camera2/X gọi extensions-interface để đạt được ba luồng ứng dụng.

Luồng ứng dụng 1: Kiểm tra khả năng sử dụng tiện ích

AdvancedAppFlow1

Hình 8. Luồng ứng dụng 1 trên Advanced Extender

Trước tiên, ứng dụng sẽ kiểm tra xem tiện ích đã cho có được hỗ trợ hay không.

Luồng ứng dụng 2: Truy vấn thông tin

AdvancedAppFlow2

Hình 9. Luồng ứng dụng 2 trên Advanced Extender

Sau khi gọi AdvancedExtenderImpl.init(), ứng dụng có thể truy vấn sau đây là thông tin về AdvancedExtenderImpl:

  • Độ trễ chụp ảnh vẫn ước tính: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() trả về phạm vi độ trễ chụp để ứng dụng đánh giá xem nó có phù hợp để bật tiện ích cho trường hợp hiện tại.

  • Độ phân giải được hỗ trợ để xem trước mà vẫn chụp được ảnh:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() trả về một bản đồ thành danh sách kích thước được hỗ trợ cho định dạng nền tảng xem trước và kích thước. Nhà sản xuất thiết bị gốc phải hỗ trợ định dạng PRIVATE tối thiểu.

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() trả về được hỗ trợ định dạng và kích thước cho bề mặt chụp ảnh tĩnh. OEM phải hỗ trợ cả hai Đầu ra định dạng JPEGYUV_420_888.

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() trả về các kích thước được hỗ trợ cho luồng YUV_420_888 bổ sung dùng để phân tích hình ảnh. Nếu nền tảng YUV phân tích hình ảnh không được hỗ trợ, getSupportedYuvAnalysisResolutions() cần trả về null hoặc một danh sách trống.

  • Các khoá/kết quả yêu cầu chụp có sẵn (được thêm trong extensions-interface 1.3.0): Camera2/X gọi các phương thức sau để truy xuất ảnh chụp được hỗ trợ yêu cầu khoá và khoá kết quả từ quá trình triển khai của bạn:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

Để biết thêm thông tin, hãy xem Hỗ trợ kết quả và khoá yêu cầu chụp.

Luồng ứng dụng 3: Xem trước/chụp ảnh tĩnh khi bật tiện ích

AdvancedAppFlow3

Hình 10. Luồng ứng dụng 3 trên Advanced Extender

Sơ đồ trên cho thấy quy trình chính để bắt đầu xem trước và vẫn chụp trong loại Advanced Extender. Hãy cùng tìm hiểu từng bước.

  1. Thực thể SessionProcessorImpl

    Quy trình triển khai Advanced Extender cốt lõi nằm trong SessionProcessorImpl, tức là chịu trách nhiệm cung cấp cấu hình phiên tùy chỉnh và gửi chụp các yêu cầu để bắt đầu bản xem trước mà vẫn chụp được yêu cầu. AdvancedExtenderImpl.createSessionProcessor() được gọi để trả về Thực thể SessionProcessorImpl.

  2. initSession

    SessionProcessorImpl.initSession() sẽ khởi chạy phiên của tiện ích. Đây là nơi bạn phân bổ tài nguyên và trả về cấu hình phiên cho đang chuẩn bị một CameraCaptureSession.

    Đối với tham số đầu vào, Camera2/X chỉ định cấu hình bề mặt đầu ra để xem trước, chụp ảnh tĩnh và phân tích hình ảnh YUV (không bắt buộc). Kết quả này cấu hình bề mặt (OutputSurfaceImpl) chứa giao diện, kích thước và hình ảnh được truy xuất bằng các phương thức sau trong AdvancedExtenderImpl:

    • getSupportedPreviewOutputResolutions()
    • getSupportedCaptureOutputResolutions()
    • getSupportedYuvAnalysisResolutions()

    Bạn phải trả về một thực thể Camera2SessionConfigImpl, trong đó bao gồm một thực thể danh sách phiên bản Camera2OutputConfigImpl và thông số phiên đã dùng để định cấu hình CameraCaptureSession. Bạn chịu trách nhiệm về xuất hình ảnh máy ảnh chính xác vào các bề mặt đầu ra được truyền vào Camera2/X. Sau đây là một số tuỳ chọn để bật dữ liệu đầu ra:

    • Xử lý trong lớp trừu tượng phần cứng (HAL) cho máy ảnh: Bạn có thể trực tiếp thêm các bề mặt đầu ra đến CameraCaptureSession bằng SurfaceOutputConfigImpl trong quá trình triển khai. Thao tác này sẽ định cấu hình bề mặt đầu ra được cung cấp cho camera và cho phép lớp trừu tượng phần cứng (HAL) của máy ảnh xử lý hình ảnh.
    • Đang xử lý nền tảng ImageReader trung gian (RAW, YUV, v.v.): Thêm ImageReader trung gian sang CameraCaptureSession cùng với Thực thể ImageReaderOutputConfigImpl.

      Bạn cần xử lý hình ảnh trung gian rồi viết hình ảnh kết quả vào giao diện đầu ra.

    • Sử dụng tính năng chia sẻ bề mặt Camera2: Sử dụng tính năng chia sẻ bề mặt với một nền tảng khác bằng cách thêm bản sao Camera2OutputConfigImpl bất kỳ vào Phương thức getSurfaceSharingOutputConfigs() của một phương thức khác Thực thể Camera2OutputConfigImpl. Định dạng và kích thước bề mặt phải là .

    Tất cả Camera2OutputConfigImpl bao gồm SurfaceOutputConfigImplImageReaderOutputConfigImpl phải có một mã nhận dạng duy nhất (getId()). dùng để chỉ định bề mặt đích và truy xuất hình ảnh từ ImageReaderOutputConfigImpl.

  3. onCaptureSessionStartRequestProcessorImpl

    Khi CameraCaptureSession khởi động và khung Máy ảnh gọi onConfigured(), sau đó Camera2/X sẽ gọi SessionProcessorImpl.onCaptureSessionStart() với yêu cầu Camera2 trình bao bọc RequestProcessImpl. Camera2/X triển khai RequestProcessImpl, cho phép bạn thực thi các yêu cầu chụptruy xuất hình ảnh nếu sử dụng ImageReaderOutputConfigImpl.

    Các API RequestProcessImpl tương tự như Camera2 CameraCaptureSession API liên quan đến việc thực thi yêu cầu. Có những điểm khác biệt như sau:

    • Bề mặt mục tiêu được chỉ định theo mã nhận dạng của Thực thể Camera2OutputConfigImpl.
    • Khả năng truy xuất hình ảnh của ImageReader.

    Bạn có thể gọi RequestProcessorImpl.setImageProcessor() bằng một thuộc tính Mã Camera2OutputConfigImpl để đăng ký một thực thể ImageProcessorImpl cho nhận hình ảnh.

    Thực thể RequestProcessImpl sẽ không còn hợp lệ sau khi gọi Camera2/X SessionProcessorImpl.onCaptureSessionEnd().

  4. Bắt đầu dùng thử và chụp ảnh

    Khi triển khai Trình mở rộng nâng cao, bạn có thể gửi yêu cầu ghi lại thông qua giao diện RequestProcessorImpl. Camera2/X thông báo cho bạn tới bắt đầu yêu cầu lặp lại để xem trước hoặc trình tự chụp ảnh tĩnh bằng cách đang gọi SessionProcessorImpl#startRepeatingSessionProcessorImpl#startCapture. Bạn nên gửi ảnh chụp để đáp ứng các yêu cầu xem trước và chụp ảnh tĩnh này.

    Camera2/X cũng đặt tham số yêu cầu chụp thông qua SessionProcessorImpl#setParameters. Bạn phải đặt các thông số yêu cầu này (nếu thông số được hỗ trợ) trên cả yêu cầu lặp lại và yêu cầu đơn lẻ.

    Bạn phải hỗ trợ ít nhất CaptureRequest.JPEG_ORIENTATIONCaptureRequest.JPEG_QUALITY. extensions-interface 1.3.0 hỗ trợ yêu cầu và khoá kết quả, hiển thị bằng các phương pháp sau:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys()

    Khi nhà phát triển đặt các khoá trong danh sách getAvailableCaptureRequestKeys, bạn phải bật các thông số và đảm bảo thu thập kết quả chứa các khoá trong danh sách getAvailableCaptureResultKeys.

  5. startTrigger

    SessionProcessorImpl.startTrigger() được gọi để bắt đầu điều kiện kích hoạt, chẳng hạn như dưới dạng CaptureRequest.CONTROL_AF_TRIGGERCaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER. Bạn có thể bỏ qua mọi thu thập khoá yêu cầu không được quảng cáo AdvancedExtenderImpl.getAvailableCaptureRequestKeys().

    startTrigger() đã được hỗ trợ kể từ phiên bản extensions-interface 1.3.0. Nó cho phép các ứng dụng triển khai chế độ nhấn để lấy nét và đèn flash bằng các tiện ích.

  6. Dọn dẹp

    Khi kết thúc phiên chụp, SessionProcessorImpl.onCaptureSessionEnd() được gọi trước khi đóng CameraCaptureSession. Sau khi phiên chụp đã kết thúc, deInitSession() sẽ dọn dẹp.

Hỗ trợ xem trước, chụp ảnh tĩnh và phân tích hình ảnh

Bạn nên áp dụng tiện ích cho cả bản xem trước và trường hợp sử dụng vẫn ghi lại được. Tuy nhiên, nếu độ trễ quá cao nên không thể hiển thị bản xem trước một cách suôn sẻ, bạn có thể chỉ áp dụng tiện ích khi chụp ảnh tĩnh.

Đối với loại Basic Extender (Bộ mở rộng cơ bản), bất kể có bật tiện ích để xem trước hay không, bạn phải triển khai cả ImageCaptureExtenderImplPreviewExtenderImpl cho một tiện ích cụ thể. Thông thường, một ứng dụng cũng sử dụng luồng YUV để phân tích nội dung hình ảnh như tìm mã QR hoặc văn bản. Để hỗ trợ tốt hơn cho trường hợp sử dụng này , bạn nên hỗ trợ kết hợp luồng xem trước, chụp ảnh tĩnh và Luồng YUV_420_888 để định cấu hình CameraCaptureSession. Điều này có nghĩa là nếu bạn triển khai bộ xử lý, thì bạn phải hỗ trợ luồng tổ hợp 3 luồng YUV_420_888.

Đối với Advanced Extender, Camera2/X truyền 3 bề mặt đầu ra đến Cuộc gọi SessionProcessorImpl.initSession(). Các giao diện đầu ra này là để xem trước , chụp ảnh tĩnh và phân tích ảnh. Bạn phải đảm bảo rằng bản xem trước nhưng vẫn chụp được các bề mặt đầu ra sẽ cho thấy đầu ra hợp lệ. Tuy nhiên, đối với hình ảnh giao diện đầu ra phân tích, hãy đảm bảo nó chỉ hoạt động khi không có giá trị rỗng. Nếu phương thức triển khai không thể hỗ trợ luồng phân tích hình ảnh, bạn có thể trả về một giá trị trống trong AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions(). Chiến dịch này đảm bảo giao diện đầu ra phân tích hình ảnh luôn rỗng SessionProcessorImpl.initSession().

Hỗ trợ quay video

Cấu trúc của Tiện ích máy ảnh hiện tại chỉ hỗ trợ bản xem trước và vẫn nắm bắt các trường hợp sử dụng. Chúng tôi không hỗ trợ bật tiện ích trên MediaCodec hoặc MediaRecorder nền tảng để quay video. Tuy nhiên, vẫn có khả năng cho ứng dụng ghi lại kết quả xem trước.

Việc hỗ trợ các nền tảng MediaCodecMediaRecorder đang được điều tra.

Siêu dữ liệu dành riêng cho tiện ích

Đối với Android 14 trở lên, siêu dữ liệu dành riêng cho tiện ích cho phép ứng dụng khách tiện ích máy ảnh thiết lập và nhận bản ghi dành riêng cho tiện ích yêu cầu cài đặt và kết quả. Cụ thể, tiện ích máy ảnh các ứng dụng có thể sử dụng thông số yêu cầu chụp EXTENSION_STRENGTH để kiểm soát độ mạnh của phần mở rộng và kết quả thu thập EXTENSION_CURRENT_TYPE thành cho biết loại tiện ích được bật.

Ghi lại yêu cầu

Chiến lược phát hành đĩa đơn EXTENSION_STRENGTH tham số của yêu cầu thu thập kiểm soát độ mạnh của hiệu ứng hậu xử lý tiện ích. Thuộc tính tương ứng kết quả thu thập bao gồm giá trị độ mạnh mặc định nếu không đặt thông số này được khách hàng chỉ định rõ ràng. Bạn có thể áp dụng tham số này như sau cho loại phần mở rộng:

  • BOKEH: Kiểm soát độ mờ.
  • HDRNIGHT: Kiểm soát số lượng hình ảnh được hợp nhất và độ sáng của hình ảnh cuối cùng.
  • FACE_RETOUCH: Kiểm soát mức độ làm đẹp và làm đẹp da làm mượt.

Phạm vi được hỗ trợ cho tham số EXTENSION_STRENGTH là từ 0 đến 100, với 0 cho biết không có xử lý tiện ích hoặc truyền qua đơn giản và 100 cho biết độ mạnh kéo dài tối đa của hiệu ứng xử lý.

Để thêm tính năng hỗ trợ cho EXTENSION_STRENGTH, hãy sử dụng nhà cung cấp API tham số cụ thể được giới thiệu trong phiên bản 1.3.0 của thư viện tiện ích . Để biết thêm thông tin, hãy xem getAvailableCaptureRequestKeys().

Thu thập kết quả

Chiến lược phát hành đĩa đơn EXTENSION_CURRENT_TYPE thu thập kết quả cho phép triển khai tiện ích thông báo cho khách hàng về loại tiện ích.

Bởi vì các tiện ích sử dụng loại AUTO sẽ linh động chuyển đổi giữa các tiện ích chẳng hạn như HDRNIGHT tuỳ thuộc vào điều kiện cảnh, camera các ứng dụng có thể sử dụng EXTENSION_CURRENT_TYPE để hiển thị thông tin về tiện ích hiện tại được tiện ích AUTO chọn.

Ước tính độ trễ chụp ảnh vẫn theo thời gian thực

Đối với Android 14 trở lên, các ứng dụng tiện ích máy ảnh có thể truy vấn thời gian thực ước tính độ trễ dựa trên cảnh và điều kiện môi trường sử dụng getRealtimeStillCaptureLatency(). Chiến dịch này Phương pháp này cung cấp các ước tính chính xác hơn so với phương pháp getEstimatedCaptureLatencyRangeMillis() . Dựa trên ước tính độ trễ, các ứng dụng có thể quyết định bỏ qua tiện ích hoặc hiển thị chỉ báo để thông báo cho người dùng về một khoảng thời gian hoạt động đang chạy.

CameraExtensionSession.StillCaptureLatency latency;

latency = extensionSession.getRealtimeStillCaptureLatency();

// The capture latency from ExtensionCaptureCallback#onCaptureStarted() until ExtensionCaptureCallback#onCaptureProcessStarted().

latency.getCaptureLatency();

// The processing latency from  ExtensionCaptureCallback#onCaptureProcessStarted() until  the processed frame returns to the client.

latency.getProcessingLatency();

Để hỗ trợ ước tính độ trễ chụp ảnh vẫn theo thời gian thực, hãy triển khai như sau:

Lệnh gọi lại tiến trình xử lý chụp ảnh

Đối với Android 14 trở lên, các ứng dụng tiện ích máy ảnh có thể nhận lệnh gọi lại cho tiến trình xử lý ảnh vẫn chạy trong thời gian dài các toán tử. Ứng dụng có thể hiển thị tiến trình hiện tại cho người dùng để cải thiện trải nghiệm người dùng tổng thể.

Các ứng dụng có thể dùng mã sau đây để tích hợp tính năng này:

import android.hardware.camera2.CameraExtensionSession.
ExtensionCaptureCallback;

{
…
  class AppCallbackImpl extends ExtensionCaptureCallback {
…
    @Override
    public void onCaptureProcessProgressed(
      @NonNull CameraExtensionSession session,
      @NonNull CaptureRequest request,
      @IntRange(from = 0, to = 100) int progress) {
      // Update app UI with current progress
    }
  }
…
}

Để hỗ trợ lệnh gọi lại tiến trình xử lý chụp ảnh, nhà cung cấp tiện ích của bạn Việc triển khai phải gọi các lệnh gọi lại sau đây với tiến trình hiện tại giá trị:

Chụp ảnh tĩnh ở dạng Postview

Đối với Android 14 trở lên, các tiện ích máy ảnh có thể cung cấp chế độ xem bài đăng (hình ảnh xem trước) bằng cách sử dụng setPostviewOutputConfiguration. Để cải thiện trải nghiệm người dùng, ứng dụng có thể hiển thị hình ảnh sau chế độ xem dưới dạng phần giữ chỗ khi tiện ích đang phải chịu độ trễ xử lý tăng lên, và thay thế hình ảnh khi có hình ảnh cuối cùng. Các ứng dụng có thể định cấu hình và đưa ra yêu cầu chụp ảnh hậu kỳ bằng cách sử dụng mã tham chiếu sau:

{
…
if (!CameraExtensionCharacteristics.isPostviewAvailable()) {
    continue;
}
…
ExtensionSessionConfiguration extensionConfiguration = new
        ExtensionSessionConfiguration(
                CameraExtensionCharacteristics.EXTENSION_NIGHT,
                outputConfig,
                backgroundExecutor,
                extensionSessionStateCallback
    );

extensionConfiguration.setPostviewOutputConfiguration(
    postviewImageOutput);
…
CaptureRequest.Builder captureRequestBuilder =
    cameraDevice.createCaptureRequest(
        CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(stillImageReader.getSurface());
captureRequestBuilder.addTarget(postviewImageSurface);

CaptureRequest captureRequest = captureRequestBuilder.build();
…
}

Để hỗ trợ chụp ảnh vẫn trong chế độ xem hậu kỳ, việc triển khai nhà cung cấp của bạn phải triển khai sau:

Hỗ trợ đầu ra SurfaceView

Đối với Android 14 trở lên, các ứng dụng tiện ích máy ảnh có thể sử dụng đường dẫn kết xuất bản xem trước được tối ưu hoá về hiệu suất và hiệu suất bằng cách đăng ký SurfaceView cho bản xem trước đầu ra cho các yêu cầu lặp lại.

Để hỗ trợ đầu ra SurfaceView, việc triển khai tiện ích nhà cung cấp của bạn phải có khả năng truyền trực tuyến và xuất bản xem trước tới các thực thể SurfaceView. Người nhận xác minh rằng định dạng này được hỗ trợ, chạy SurfaceViewExtensionPreviewTest.java mô-đun CTS.

Loại phiên dành riêng cho nhà cung cấp

Tính năng này cho phép triển khai tiện ích của nhà cung cấp để chọn một loại phiên cụ thể của nhà cung cấp. Loại phiên này sẽ được thiết lập trong phiên chụp ảnh nội bộ thay vì giá trị mặc định.

Tính năng này hoạt động hoàn toàn trong khung và bộ phần mềm của nhà cung cấp, đồng thời không có tác động gì đến API ứng dụng/công khai.

Để chọn loại phiên dành riêng cho nhà cung cấp, hãy triển khai các cách sau cho thư viện tiện ích của bạn: * ExtenderStateListener.onSessionType() đối với các tiện ích cơ bản * Camera2SessionConfigImpl.getSessionType() đối với tiện ích nâng cao

Nhật ký phiên bản giao diện tiện ích

Bảng sau đây cho thấy nhật ký phiên bản giao diện của Tiện ích máy ảnh. Bạn phải luôn triển khai thư viện nhà cung cấp với phiên bản mới nhất.

Phiên bản Tính năng bổ sung
1.0.0
  • Xác minh phiên bản
    • ExtensionVersionImpl
  • Thanh nối dài cơ bản
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Khởi chạy thư viện
    • InitializerImpl
  • Hiển thị độ phân giải được hỗ trợ
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • Trình mở rộng nâng cao
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Nhận độ trễ chụp ước tính
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Hiển thị khoá yêu cầu chụp/khoá kết quả được hỗ trợ
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeysgetAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeysgetAvailableCaptureResultKeys
    • Cuộc gọi process() mới sẽ thực hiện ProcessResultImpl trong PreviewImageProcessorImplCaptureProcessorImpl
    • Hỗ trợ yêu cầu loại điều kiện kích hoạt
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Siêu dữ liệu dành riêng cho tiện ích
  • Động vẫn ghi lại các ước tính độ trễ
  • Lệnh gọi lại tiến trình xử lý chụp ảnh
  • Chụp ảnh tĩnh ở dạng Postview
  • Hỗ trợ đầu ra SurfaceView
  • Loại phiên dành riêng cho nhà cung cấp

Cách triển khai tệp đối chiếu

Các cách triển khai thư viện nhà cung cấp OEM tham chiếu sau đây có trong frameworks/ex.

  • advancedSample: Cách triển khai cơ bản của Advanced Extender.

  • sample: Cách triển khai cơ bản của Basic Extender.

  • service_based_sample: Một phương thức triển khai minh hoạ cách lưu trữ Tiện ích Máy ảnh trong một Service. Phương thức triển khai này bao gồm các thành phần sau:

    • oem_library: Thư viện OEM của Tiện ích máy ảnh cho các API Tiện ích Camera2 và CameraX triển khai Extensions-Interface. Đây là một tín hiệu truyền chuyển tiếp cuộc gọi từ Extensions-Interface đến dịch vụ. Thư viện này đồng thời cung cấp các tệp AIDL và các lớp trình bao bọc để giao tiếp với .

      Advanced Extender được bật theo mặc định. Để bật Basic Extender, thay đổi ExtensionsVersionImpl#isAdvancedExtenderImplemented để trả về false.

    • extensions_service: Triển khai mẫu của Dịch vụ tiện ích. Thêm cách triển khai của bạn vào đây. Giao diện để triển khai trong dịch vụ này cũng tương tự như vào Extensions-Interface. Ví dụ: triển khai IAdvancedExtenderImpl.Stub thực hiện các thao tác tương tự như AdvancedExtenderImpl. ImageWrapperTotalCaptureResultWrapper là bắt buộc để làm cho ImageTotalCaptureResult có thể đóng gói.

Thiết lập thư viện nhà cung cấp trên thiết bị

Thư viện nhà cung cấp OEM không được tích hợp vào ứng dụng; đường dẫn đó được tải từ thiết bị trong thời gian chạy bằng Camera2/X. Trong CameraX, thẻ <uses-library> khai báo rằng thư viện androidx.camera.extensions.impl, được xác định trong AndroidManifest.xml của thư viện camera-extensions, là một phần phụ thuộc của CameraX và phải là được tải trong thời gian chạy. Trong Camera2, khung sẽ tải một dịch vụ tiện ích cũng khai báo rằng <uses-library> tải cùng một tệp Thư viện androidx.camera.extensions.impl trong thời gian chạy.

Điều này cho phép các ứng dụng bên thứ ba sử dụng tiện ích để tự động tải OEM (Nhà sản xuất thiết bị gốc) thư viện nhà cung cấp. Thư viện OEM được đánh dấu là không bắt buộc để các ứng dụng có thể chạy trên các thiết bị không có thư viện trên thiết bị. Camera2/X tự động xử lý hành vi này khi một ứng dụng cố gắng dùng máy ảnh miễn là nhà sản xuất thiết bị đặt thư viện OEM trên thiết bị để ứng dụng có thể phát hiện được.

Để thiết lập thư viện OEM trên thiết bị, hãy làm như sau:

  1. Thêm tệp quyền mà thẻ <uses-library> yêu cầu, bằng cách sử dụng định dạng sau: /etc/permissions/ANY_FILENAME.xml. Cho ví dụ: /etc/permissions/camera_extensions.xml. Các tệp trong thư mục này thư mục này cung cấp bản đồ ánh xạ của thư viện có tên trong <uses-library> đến đường dẫn tệp thực trên thiết bị.
  2. Sử dụng ví dụ bên dưới để thêm thông tin bắt buộc vào tệp.

    • Giá trị của name phải là androidx.camera.extensions.impl thư viện mà CameraX tìm kiếm.
    • file là đường dẫn tuyệt đối của tệp chứa triển khai tiện ích (ví dụ: /system/framework/androidx.camera.extensions.impl.jar).
    <?xml version="1.0" encoding="utf-8"?>
    <permissions>
        <library name="androidx.camera.extensions.impl"
                 file="OEM_IMPLEMENTED_JAR" />
    </permissions>
    

Trong Android 12 trở lên, các thiết bị hỗ trợ CameraX tiện ích phải có thuộc tính ro.camerax.extensions.enabled được đặt thành true, cho phép truy vấn xem thiết bị có hỗ trợ tiện ích hay không. Để thực hiện việc này, hãy thêm dòng sau vào tệp make thiết bị:

PRODUCT_VENDOR_PROPERTIES += \
    ro.camerax.extensions.enabled=true \

Xác nhận kết quả

Để kiểm thử việc triển khai thư viện nhà cung cấp OEM trong giai đoạn phát triển, hãy sử dụng ứng dụng mẫu tại androidx-main/camera/integration-tests/extensionstestapp/! chạy qua nhiều tiện ích của nhà cung cấp.

Sau khi triển khai xong, hãy sử dụng công cụ xác thực tiện ích camera chạy các kiểm tra tự động và thủ công để xác minh rằng thư viện nhà cung cấp được triển khai chính xác.

Chế độ cảnh mở rộng so với tiện ích camera

Đối với tiện ích bokeh, ngoài việc phơi sáng ảnh bằng tiện ích máy ảnh, bạn có thể hiển thị tiện ích bằng cách sử dụng chế độ cảnh mở rộng, được bật thông qua thời gian CONTROL_EXTENDED_SCENE_MODE . Để biết thêm thông tin về cách triển khai, hãy xem bài viết Hiệu ứng bokeh của máy ảnh.

Chế độ cảnh mở rộng có ít hạn chế hơn so với các tiện ích máy ảnh cho các ứng dụng camera2. Ví dụ: bạn có thể bật chế độ cảnh mở rộng trong một thực thể CameraCaptureSession thông thường hỗ trợ truyền phát linh hoạt kết hợp và thu thập các tham số yêu cầu. Ngược lại, tiện ích máy ảnh chỉ hỗ trợ một nhóm các loại luồng cố định và hỗ trợ hạn chế việc thu thập tham số yêu cầu.

Nhược điểm của chế độ cảnh mở rộng là bạn chỉ có thể triển khai trong HAL của máy ảnh, có nghĩa là màn hình này phải được xác minh là hoạt động trên tất cả các thành phần điều khiển trực giao dành cho nhà phát triển ứng dụng.

Bạn nên phơi sáng hiệu ứng bokeh bằng cả chế độ cảnh mở rộng và Máy ảnh Các tiện ích vì ứng dụng có thể ưu tiên sử dụng một API cụ thể để bật hiệu ứng bokeh. Trước tiên, bạn nên sử dụng chế độ cảnh mở rộng vì đây là chế độ linh hoạt để ứng dụng bật phần mở rộng về hiệu ứng bokeh. Sau đó, bạn có thể triển khai giao diện của tiện ích máy ảnh dựa trên chế độ cảnh mở rộng. Nếu triển khai Hiệu ứng bokeh trong HAL của máy ảnh rất khó, chẳng hạn như vì cần phải có một ảnh chụp bộ xử lý chạy trong lớp ứng dụng để xử lý hình ảnh, bạn nên triển khai tiện ích bokeh thông qua giao diện Tiện ích máy ảnh.

Câu hỏi thường gặp

Có quy định hạn chế nào về cấp độ API không?

Có. Điều này phụ thuộc vào bộ tính năng API Android mà OEM yêu cầu triển khai thư viện nhà cung cấp. Ví dụ: ExtenderStateListener.onPresetSession() sử dụng SessionConfiguration.setSessionParameters() để thiết lập bộ thẻ cơ sở. Lệnh gọi này chỉ dùng được ở cấp độ API 28 trở lên. Để biết chi tiết về các phương thức giao diện cụ thể, hãy xem Tài liệu tham khảo API.