Tiện ích mở rộng máy ảnh

Các nhà sản xuất thiết bị có thể cung cấp các tiện ích mở rộng như hiệu ứng xóa phông, chế độ ban đêm và HDR cho các nhà phát triển bên thứ ba thông qua giao diện Tiện ích mở rộng máy ảnh do thư viện nhà cung cấp OEM cung cấp. Các nhà phát triển có thể sử dụng API tiện ích mở rộng Camera2API tiện ích mở rộng CameraX để truy cập các tiện ích mở rộng được triển khai trong thư viện nhà cung cấp OEM.

Để biết danh sách các tiện ích mở rộng được hỗ trợ giống nhau trên Camera2 và CameraX, hãy xem API tiện ích mở rộng CameraX . Nếu bạn muốn thêm tiện ích mở rộng, hãy gửi lỗi bằng Trình theo dõi sự cố .

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

Ngành kiến ​​​​trúc

Sơ đồ sau mô tả kiến ​​trúc của giao diện Tiện ích mở rộng Máy ảnh hoặc extensions-interface : Ngành kiến ​​​​trúc

Hình 1. Sơ đồ kiến ​​trúc Tiện ích mở rộng Camera

Như được hiển thị trong sơ đồ, để hỗ trợ Tiện ích mở rộng 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ư viện nhà cung cấp OEM của bạn cho phép hai API: API tiện ích mở rộng CameraXAPI tiện ích mở rộng Camera2 , được các ứng dụng CameraX và Camera2 sử dụng tương ứng để truy cập các tiện ích mở rộng 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 các tệp camera-extensions-stub vào dự án thư viện hệ thống. Các tệp này xác định giao diện Tiện ích mở rộng máy ảnh.

Các tệp camera-extensions-stub được chia thành các loại sau:

Các tệp giao diện cần thiết (khô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

Triển khai bắt buộc (thêm triển khai của bạn)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

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

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

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

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

Các lớp mở rộng tự động (triển khai nó nếu Tự động mở rộng được hỗ trợ)

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

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

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

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

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

Tiện ích (tùy chọn, có thể xóa)

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

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

Hãy cùng tìm hiểu cách API Tiện ích mở rộng Camera2 và CameraX tương tác với thư viện của nhà cung cấp để kích hoạt tiện ích mở rộng. Sơ đồ sau đây minh họa quy trình từ đầu đến cuối bằng cách sử dụng tiện ích mở rộng Đêm làm ví dụ:

Dòng chính

Hình 2. Thực hiện kéo dài thời gian 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 các phiên bản được hỗ trợ của Camera2/X.

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

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

  3. Khởi tạo các lớp Extender:

    Khởi tạo các lớp Extender cho phần mở rộng. Có 2 loại Extender: Basic Extender và Advanced Extender. Bạn phải triển khai một loại Bộ mở rộng cho tất cả Tiện ích mở rộng. Để biết thêm thông tin, hãy xem Bộ mở rộng cơ bản và Bộ mở rộng nâng cao .

    Camera2/X khởi tạo và tương tác với các lớp Extender để truy xuất thông tin và kích hoạt tiện ích mở rộng. Đối với một tiện ích mở rộng nhất định, Camera2/X có thể khởi tạo các lớp Extender nhiều lần. Do đó, đừng thực hiện việc khởi tạo nặng nhọc trong hàm tạo hoặc lệnh gọi init() . Chỉ thực hiện các công việc nặng khi phiên camera sắp bắt đầu, 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 mở rộng Ban đêm, các lớp Bộ mở rộng sau được khởi tạo cho loại Bộ mở rộng cơ bản:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    Và đối với loại Advanced Extender:

    • NightAdvancedExtenderImpl.java
  4. Kiểm tra tính khả dụng của tiện ích mở rộng:

    Trước khi bật tiện ích mở rộng, isExtensionAvailable() sẽ kiểm tra xem tiện ích mở rộng có sẵn trên ID camera được chỉ định thông qua phiên bản Extender hay không.

  5. Khởi tạo Extender với thông tin camera:

    Camera2/X gọi init() trên phiên bản Extender và chuyển cho nó ID camera và CameraCharacteristics .

  6. Thông tin truy vấn:

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

  7. Kích hoạt tiện ích mở rộng trên Extender:

    Lớp Extender cung cấp tất cả các giao diện cần thiết để kích hoạt lớp này. Nó cung cấp một cơ chế để kết nối quá trình triển khai OEM vào quy trình Camera2 chẳng hạn như đưa các tham số yêu cầu chụp hoặc kích hoạt bộ xử lý hậu kỳ.

    Đối với loại Bộ mở rộng nâng cao, Camera2/X tương tác với SessionProcessorImpl để bật tiện ích mở rộng. Camera2/X truy xuất phiên bản SessionProcessorImpl bằng cách gọi createSessionProcessor() trên Extender.

Các phần sau đây mô tả luồng mở rộng chi tiết hơn.

Xác minh phiên bản

Khi tải thư viện của nhà cung cấp OEM từ thiết bị trong thời gian chạy, Camera2/X sẽ xác minh xem thư viện có tương thích với phiên bản extensions-interface 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ó phiên bản chính và phụ được sử dụng trong quá trình xác minh phiên bản.

Để xác minh phiên bản, Camera2/X gọi ExtensionVersionImpl.checkApiVersion() bằng phiên bản extensions-interface được hỗ trợ. Sau đó, Camera2/X sử dụng phiên bản được thư viện OEM báo cáo để xác định xem tiện ích mở rộng có thể được bật hay không và nó sẽ kích hoạt những khả năng nào.

Khả năng tương thích phiên bản chính

Nếu các phiên bản chính của giao diện tiện ích mở rộng giữa Camera2/X và thư viện của nhà cung cấp khác nhau thì phiên bản đó được coi là không tương thích và tiện ích mở rộng 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 đảm bảo khả năng tương thích ngược với các thư viện của nhà cung cấp OEM được xây dựng bằng các phiên bản extensions-interface trước đó. Ví dụ: nếu Camera2/X hỗ trợ extensions-interface 1.3.0 thì thư viện của nhà cung cấp OEM đã triển khai 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 sẽ đả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 về phía trước

Khả năng tương thích về phía trước với các thư viện của nhà cung cấp extensions-interface mới hơn tùy thuộc vào bạn, OEM. Nếu bạn cần một số tính năng để triển khai tiện ích mở rộng, bạn có thể muốn bật tiện ích mở rộng bắt đầu từ một phiên bản nhất định. Trong trường hợp này, 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ế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 tiện ích mở rộng.

Khởi tạo thư viện nhà cung cấp

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

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 của nhà cung cấp OEM gọi OnExtensionsInitializedCallback.onSuccess() để thông báo hoàn tất quá trình khởi tạo.

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

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

Có hai loại extensions-interface : Basic Extender và Advanced Extender. Advanced Extender đã được hỗ trợ kể từ extensions-interface 1.2.0.

Triển khai Basic Extender cho các tiện ích mở rộng xử lý hình ảnh trong máy ảnh HAL hoặc sử dụng bộ xử lý hậu kỳ có khả năng xử lý luồng YUV.

Triển khai Advanced Extender cho các tiện ích mở rộng cần tùy chỉnh cấu hình luồng Camera2 và gửi yêu cầu chụp khi cần.

Xem bảng sau để so sánh:

Bộ mở rộng cơ bản Bộ mở rộng nâng cao
Cấu hình luồng đã sửa
Xem trước: PRIVATE hoặc YUV_420_888 (nếu có bộ xử lý)
Vẫn chụp: JPEG hoặc YUV_420_888 (nếu có bộ xử lý)
Tùy chỉnh bởi OEM.
Gửi yêu cầu chụp Chỉ Camera2/X mới có thể gửi yêu cầu chụp. Bạn có thể đặt tham số cho những 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 và gửi tất cả hình ảnh cũng như kết quả chụp đến bộ xử lý. Một phiên bản RequestProcessorImpl được cung cấp cho bạn để thực hiện yêu cầu chụp 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 yêu cầu lặp lại để xem trước và bắt đầu trình tự chụp ảnh tĩnh tương ứng.

Móc trong đường ống camera
  • onPresetSession cung cấp các tham số phiên.
  • onEnableSession gửi một yêu cầu ngay sau khi CameraCaptureSession được định cấu hình.
  • onDisableSession gửi một yêu cầu trước khi CameraCaptureSession bị đóng.
  • initSession khởi tạo và trả về cấu hình phiên camera2 tùy chỉnh để tạo phiên chụp.
  • onCaptureSessionStart được gọi ngay sau khi CameraCaptureSession được định cấu hình.
  • onCaptureSessionEnd được gọi trước khi CameraCaptureSession bị đóng.
Phù hợp với Các tiện ích mở rộng được triển khai trong máy ảnh HAL hoặc trong bộ xử lý xử lý hình ảnh YUV.
  • Có triển khai dựa trên Camera2 cho các tiện ích mở rộng.
  • Cần cấu hình luồng tùy 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 mở rộng Camera2: Android 13 trở lên
Tiện ích mở rộng CameraX: camera-extensions 1.1.0 trở lên
Tiện ích mở rộng Camera2: Android 12L trở lên
Tiện ích mở rộng CameraX: camera-extensions 1.2.0-alpha03 trở lên

Luồng ứng dụng

Bảng sau đây hiển thị ba loại luồng ứng dụng và các lệnh gọi API Tiện ích mở rộng máy ảnh tương ứng của chúng. Mặc dù Camera2/X cung cấp các API này nhưng bạn phải triển khai đúng thư viện của nhà cung cấp để hỗ trợ các quy trình này. Chúng tôi sẽ mô tả chi tiết hơn trong phần sau.

Tiện ích mở rộng Camera2 Tiện ích mở rộng CameraX
Tính khả dụng của tiện ích mở rộng truy vấn CameraExtensionCharacteristics . getSupportedExtensions ExtensionsManager. isExtensionAvailable
Thông tin truy vấn 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 mở rộng CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector bindToLifecycle(lifecycleOwner, cameraSelector, xem trước, ...)

Bộ mở rộng cơ bản

Giao diện Basic Extender cung cấp các móc nối vào một số vị trí trong hệ thống camera. Mỗi loại tiện ích mở rộng có các lớp Extender tương ứng mà OEM cần triển khai.

Bảng sau liệt kê các lớp Extender mà OEMS cần triển khai cho từng tiện ích mở rộng:

Các lớp mở rộng để thực hiện
Đêm NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java HdrImageCaptureExtenderImpl.java
Tự động AutoPreviewExtenderImpl.java AutoImageCaptureExtenderImpl.java
Hiệu ứng mờ ảo BokehPreviewExtenderImpl.java BokehImageCaptureExtenderImpl.java
Chỉnh sửa khuôn mặt BeautyPreviewExtenderImpl.java BeautyImageCaptureExtenderImpl.java

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

Basic Extender có các khả năng sau:

  • Chèn các tham 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à kết thúc phiên chụp và gửi một yêu cầu để thông báo cho HAL cùng với các tham số được trả về ( onEnableSession , onDisableSession ).
  • Chèn các tham số chụp cho yêu cầu ( PreviewExtenderImpl.getCaptureStage , ImageCaptureExtenderImpl.getCaptureStages ).
  • Thêm bộ xử lý để xem trước và vẫn chụp 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 được đề cập ở trên.

Luồng ứng dụng 1: Kiểm tra tính khả dụng của tiện ích mở rộng

BasicExtenderAppFlow1

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

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

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

Luồng ứng dụng 2: Thông tin truy vấn

BasicExtenderAppFlow2

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

Sau khi xác định xem tiện ích mở rộng có khả dụng hay không, ứng dụng sẽ truy vấn thông tin sau trước khi bật tiện ích mở rộng.

  • Phạm vi độ trễ chụp vẫn: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange trả về phạm vi độ trễ chụp để ứng dụng đánh giá xem liệu việc bật tiện ích mở rộng cho trường hợp hiện tại có phù hợp hay không.

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

  • Các khóa 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 các khóa yêu cầu chụp và khóa kết quả được hỗ trợ từ quá trình triển khai của bạn:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

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

Luồng ứng dụng 3: Xem trước/chụp ảnh tĩnh khi bật tiện ích mở rộng (triển khai HAL)

BasicExtenderAppFlow3

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

Sơ đồ trên minh họa quy trình chính cho phép xem trước và vẫn chụp bằng tiện ích mở rộng mà không cần bất kỳ bộ xử lý nào. Điều này có nghĩa là camera HAL xử lý phần mở rộng.

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

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

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() . Hơn nữa, yêu cầu chụp ảnh tĩ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 camera kết thúc. Bạn có thể giải phóng tài nguyên trong onDeinit() .

Bộ xử lý xem trước

Ngoài HAL của máy ảnh, bạn cũng có thể triển khai các tiện ích mở rộng 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ó bộ xử lý. Hình ảnh được xử lý trong máy ảnh 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 với các tham 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 phiên RequestUpdateProcessorImpl xử lý phiên bản TotalCaptureResult và trả về một phiên bản 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 bộ xử lý để xử lý hình ảnh YUV_420_888 và ghi đầu ra lên bề mặt PRIVATE .

    Bạn cần triển khai và trả về một phiên bản PreviewImageProcessorImpl trong PreviewExtenderImpl.getProcessor . Bộ xử lý chịu trách nhiệm xử lý hình ảnh đầu vào YUV_420_888 . Nó sẽ ghi kết quả đầu ra sang định dạng xem trước PRIVATE . Camera2/X sử dụng bề mặt YUV_420_888 thay vì PRIVATE để định cấu CameraCaptureSession để xem trước.

    Xem hình minh họa sau đây để biết quy trình:

Xem trướcBộ xử lý

Hình 6. Luồng xem trước với PreviewImageProcessorImpl

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

  • onOutputSurface(Surface surface, int imageFormat) đặt bề mặt đầu ra cho bộ xử lý. Đối với PreviewImageProcessorImpl , imageFormat là định dạng pixel 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 hình ảnh đầu vào. Hiện tại chỉ có thể là YUV_420_888 .

Bộ 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ề phiên bản CaptureProcessorImpl bằng cách sử dụng ImageCaptureExtenderImpl.getCaptureProcessor . Bộ xử lý có trách nhiệm xử lý danh sách các hình ảnh YUV_420_888 đã chụp và các phiên bản TotalCaptureResult rồi ghi kết quả đầu ra lên bề mặt YUV_420_888 .

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

Xem dòng chảy trong sơ đồ dưới đây:

Bộ xử lý chụp

Hình 7. Vẫn chụp luồng 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() với YUV_420_888 .
    • CaptureProcessorImpl.onResolutionUpdate() với kích thước hình ảnh đầu vào.
    • CaptureProcessorImpl.onOutputSurface() với bề mặt YUV_420_888 đầu ra.
  2. ImageCaptureExtenderImpl.getCaptureStages trả về danh sách CaptureStageImpl , trong đó mỗi phần tử ánh xạ tới một phiên bản CaptureRequest với các thông số chụp được gửi bởi Camera2/X. Ví dụ: nếu trả về danh sách ba phiên bản CaptureStageImpl , Camera2/X sẽ gửi ba yêu cầu chụp với các thông số chụp tương ứng bằng cách sử dụng API captureBurst .

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

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

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

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

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

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() trả về các khóa yêu cầu chụp được quá trình triển khai của bạn hỗ trợ.
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() trả về các khóa kết quả chụp có trong kết quả chụp.

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

Xem định nghĩa của giao diện CaptureProcessorImpl bên dưới làm ví dụ. Trong extensions-interface 1.3.0 trở lên, lệnh gọi process() thứ hai đượ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 thông thường của máy ảnh như thu phóng, chạm để lấy nét, đèn flash và bù phơi sáng, chúng tôi khuyên bạn nên hỗ trợ các phím sau cho cả yêu cầu chụp và kết quả chụp:

  • 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
  • Tốc biến:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • Bù phơi sáng:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

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

Bộ mở rộng nâng cao

Advanced Extender là một loại 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 extensions-interface 1.2.0. Tùy thuộc vào nhà sản xuất thiết bị, tiện ích mở rộng có thể được triển khai trong lớp ứng dụng, điều này phụ thuộc vào các yếu tố sau:

  • Cấu hình luồng tùy chỉnh: Định cấu hình các luồng tùy chỉnh như luồng RAW hoặc có nhiều luồng cho các ID máy ảnh vật lý khác nhau.

  • Khả năng gửi yêu cầu Camera2: Hỗ trợ logic tương tác phức tạp 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 trình bao bọc hoặc lớp trung gian để bạn có thể tùy chỉnh cấu hình luồng và gửi yêu cầu chụp theo yêu cầu.

Các tập tin để thực hiện

Để chuyển sang 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 mở rộng, OEM phải triển khai các lớp Extender tương ứng. Các tệp triển khai Advanced Extender nằm trong gói nâng cao .

Các lớp mở rộng để thực hiện
Đêm advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Tự động advanced/AutoAdvancedExtenderImpl.java
Hiệu ứng mờ ảo advanced/BokehAdvancedExtenderImpl.java
Chỉnh sửa khuôn mặt advanced/BeautyAdvancedExtenderImpl.java

Chúng tôi sử dụng AdvancedExtenderImpl làm trình giữ chỗ trong ví dụ sau. Thay thế bằng tên của tệp Extender cho tiện ích mở rộng bạn đang 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 tính khả dụng của tiện ích mở rộng

AdvancedAppFlow1

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

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

Luồng ứng dụng 2: Thông tin truy vấn

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 thông tin sau trên AdvancedExtenderImpl :

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

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

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() trả về bản đồ định dạng hình ảnh cho danh sách kích thước được hỗ trợ cho định dạng và kích thước bề mặt xem trước. OEM phải hỗ trợ ít nhất định dạng PRIVATE .

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() trả về định dạng và kích thước được hỗ trợ cho bề mặt chụp ảnh tĩnh. OEM phải hỗ trợ cả đầ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 để phân tích hình ảnh. Nếu bề mặt YUV phân tích hình ảnh không được hỗ trợ, getSupportedYuvAnalysisResolutions() sẽ trả về null hoặc danh sách trống.

  • Các khóa/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 các khóa yêu cầu chụp và khóa kết quả được hỗ trợ 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ợ các khóa và kết quả 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 mở rộng

AdvancedAppFlow3

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

Sơ đồ trên hiển thị quy trình chính để bắt đầu xem trước và vẫn chụp cho loại Bộ mở rộng nâng cao. Chúng ta hãy đi qua từng bước.

  1. Phiên bản SessionProcessorImpl

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

  2. initSession

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

    Đối với các 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 tùy chọn. Cấu hình bề mặt đầu ra này ( OutputSurfaceImpl ) chứa định dạng bề mặt, kích thước và hình ảnh được truy xuất bằng các phương pháp sau trong AdvancedExtenderImpl :

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

    Bạn phải trả về một phiên bản Camera2SessionConfigImpl , bao gồm danh sách các phiên bản Camera2OutputConfigImpl và các tham số phiên được sử dụng để định cấu CameraCaptureSession . Bạn có trách nhiệm xuất hình ảnh camera chính xác ra các bề mặt đầu ra được Camera2/X chuyển vào. Dưới đây là một số tùy chọn để kích hoạt đầu ra:

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

      Bạn cần xử lý các hình ảnh trung gian và ghi hình ảnh kết quả lên bề mặt đầ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 bề mặt khác bằng cách thêm bất kỳ phiên bản Camera2OutputConfigImpl nào vào phương thức getSurfaceSharingOutputConfigs() của một phiên bản Camera2OutputConfigImpl khác. Định dạng và kích thước bề mặt phải giống hệt nhau.

    Tất cả Camera2OutputConfigImpl bao gồm SurfaceOutputConfigImplImageReaderOutputConfigImpl phải có một ID duy nhất ( getId() ), được sử dụng để chỉ định bề mặt mục tiêu và truy xuất hình ảnh từ ImageReaderOutputConfigImpl .

  3. onCaptureSessionStartRequestProcessorImpl

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

    API RequestProcessImpl tương tự như API Camera2 CameraCaptureSession về mặt thực hiện yêu cầu. Sự khác biệt là:

    • Bề mặt mục tiêu được chỉ định bởi ID của phiên bản Camera2OutputConfigImpl .
    • Khả năng truy xuất hình ảnh của ImageReader .

    Bạn có thể gọi RequestProcessorImpl.setImageProcessor() bằng ID Camera2OutputConfigImpl được chỉ định để đăng ký một phiên bản ImageProcessorImpl nhằm nhận hình ảnh.

    Phiên bản RequestProcessImpl trở nên không hợp lệ sau khi Camera2/X gọi SessionProcessorImpl.onCaptureSessionEnd() .

  4. Bắt đầu xem trước và chụp ảnh

    Khi triển khai Advanced Extender, bạn có thể gửi yêu cầu chụp thông qua giao RequestProcessorImpl . Camera2/X thông báo cho bạn bắt đầu yêu cầu lặp lại để xem trước hoặc chuỗi ảnh tĩnh bằng cách gọi SessionProcessorImpl#startRepeatingSessionProcessorImpl#startCapture tương ứng. Bạn nên gửi yêu cầu 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 tham số yêu cầu này (nếu tham 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ợ các khóa yêu cầu và kết quả, được hiển thị bằng các phương pháp sau:

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

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

  5. startTrigger

    SessionProcessorImpl.startTrigger() được gọi để khởi động trình kích hoạt, chẳng hạn như CaptureRequest.CONTROL_AF_TRIGGERCaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER . Bạn có thể bỏ qua mọi khóa yêu cầu chụp không được quảng cáo trong AdvancedExtenderImpl.getAvailableCaptureRequestKeys() .

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

  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 đã đóng, deInitSession() sẽ thực hiện việc 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 mở rộng cho cả trường hợp sử dụng xem trước và vẫn nắm bắt. Tuy nhiên, nếu độ trễ quá cao để hiển thị bản xem trước một cách mượt mà, bạn chỉ có thể áp dụng tiện ích mở rộng để chụp ảnh tĩnh.

Đối với loại Basic Extender, bất kể việc bật tiện ích mở rộng để xem trước, bạn phải triển khai cả ImageCaptureExtenderImplPreviewExtenderImpl cho tiện ích mở rộng nhất định. 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, chẳng hạn 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 giữa 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ợ kết hợp luồng của ba luồng YUV_420_888 .

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

Hỗ trợ quay video

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

Các bề mặt hỗ trợ MediaCodecMediaRecorder đang được điều tra.

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

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

Nắm bắt yêu cầu

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

  • BOKEH : Kiểm soát mức độ mờ.
  • HDRNIGHT : Kiểm soát 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 độ tăng cường thẩm mỹ và làm mịn da.

Phạm vi được hỗ trợ cho tham số EXTENSION_STRENGTH nằm trong khoảng từ 0 đến 100 , với 0 biểu thị không xử lý phần mở rộng hoặc chuyển qua đơn giản và 100 biểu thị cường độ mở rộng tối đa của hiệu ứng xử lý.

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

Ghi lại kết quả

Kết quả thu thập EXTENSION_CURRENT_TYPE cho phép triển khai tiện ích mở rộng thông báo cho khách hàng về loại tiện ích mở rộng đang hoạt động.

Vì các tiện ích mở rộng sử dụng loại AUTO tự động chuyển đổi giữa các loại tiện ích mở rộng như HDRNIGHT tùy thuộc vào điều kiện cảnh nên các ứng dụng tiện ích mở rộng máy ảnh có thể sử dụng EXTENSION_CURRENT_TYPE để hiển thị thông tin về tiện ích mở rộng hiện tại được tiện ích AUTO chọn.

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

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

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 theo thời gian thực, hãy triển khai như sau:

Ghi lại các lệnh gọi lại tiến trình xử lý

Đối với Android 14 trở lên, ứng dụng khách mở rộng máy ảnh có thể nhận lệnh gọi lại về tiến trình của các hoạt động xử lý ảnh tĩnh trong thời gian dài. Ứ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 tổng thể của người dùng.

Ứng dụng có thể sử dụng mã sau để 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ợ các lệnh gọi lại tiến trình xử lý nắm bắt, việc triển khai nhà cung cấp tiện ích mở rộng của bạn phải gọi các lệnh gọi lại sau với giá trị tiến trình hiện tại:

Postview vẫn chụp

Đối với Android 14 trở lên, tiện ích mở rộng máy ảnh có thể cung cấp chế độ xem sau (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 xem sau dưới dạng trình giữ chỗ khi tiện ích mở rộng đang gặp phải độ trễ xử lý tăng lên và thay thế hình ảnh khi có hình ảnh cuối cùng. Ứng dụng có thể định cấu hình và đưa ra yêu cầu chụp ảnh sau khi xem bằ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 tĩnh ở chế độ xem sau, việc triển khai nhà cung cấp của bạn phải triển khai như sau:

Hỗ trợ đầu ra SurfaceView

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

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

Các loại phiên cụ thể của nhà cung cấp

Tính năng này cho phép triển khai tiện ích mở rộng của nhà cung cấp chọn loại phiên cụ thể của nhà cung cấp sẽ được đặt 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à ngăn xếp nhà cung cấp và không có tác động API hiển thị ở máy khách/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 thao tác sau cho thư viện tiện ích mở rộng của bạn: * ExtenderStateListener.onSessionType() dành cho tiện ích mở rộng cơ bản * Camera2SessionConfigImpl.getSessionType() dành cho tiện ích mở rộng nâng cao

Lịch sử phiên bản giao diện tiện ích mở rộng

Bảng dưới đây hiển thị lịch sử phiên bản giao diện Camera Extension. 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 Đã thêm tính năng
1.0.0
  • Xác minh phiên bản
    • ExtensionVersionImpl
  • Bộ mở rộng cơ bản
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Khởi tạo thư viện
    • InitializerImpl
  • Hiển thị các độ phân giải được hỗ trợ
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Nhận độ trễ chụp ước tính
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Hiển thị các phím yêu cầu chụp/kết quả được hỗ trợ
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeysgetAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeysgetAvailableCaptureResultKeys
    • Lệnh gọi process() mới thực hiện ProcessResultImpl trong PreviewImageProcessorImplCaptureProcessorImpl
    • Hỗ trợ yêu cầu loại trình kích hoạt
      • AdvancedExtenderImpl.startTrigger
1.4.0
  • Siêu dữ liệu dành riêng cho tiện ích mở rộng
  • Ước tính độ trễ chụp ảnh động
  • Ghi lại các lệnh gọi lại tiến trình xử lý
  • Postview vẫn chụp
  • Hỗ trợ đầu ra SurfaceView
  • Các loại phiên cụ thể của nhà cung cấp

Thực hiện tham khảo

Việc triển khai thư viện của nhà cung cấp OEM tham khảo sau đây có sẵn trong frameworks/ex .

  • advancedSample : Triển khai cơ bản của Advanced Extender.

  • sample : Triển khai cơ bản của Basic Extender.

  • service_based_sample : Triển khai minh họa cách lưu trữ Tiện ích mở rộng máy ảnh trong Service . Việc triển khai này chứa các thành phần sau:

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

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

    • extensions_service : Một bản triển khai mẫu của Dịch vụ tiện ích mở rộng. Thêm việc thực hiện của bạn ở đây. Giao diện để triển khai trong dịch vụ tương tự như Extensions-Interface . Ví dụ: việc triển khai IAdvancedExtenderImpl.Stub thực hiện các hoạt động tương tự như AdvancedExtenderImpl . Cần có ImageWrapperTotalCaptureResultWrapper để khiến ImageTotalCaptureResult có thể phân chia được.

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; nó được tải từ thiết bị trong thời gian chạy bởi Camera2/X. Trong CameraX, thẻ <uses-library> khai báo rằng thư viện androidx.camera.extensions.impl , được xác định trong tệp AndroidManifest.xml của thư viện camera-extensions , là phần phụ thuộc của CameraX và phải được tải trong thời gian chạy. Trong Camera2, khung tải một dịch vụ tiện ích mở rộng cũng khai báo rằng <uses-library> tải cùng một thư viện androidx.camera.extensions.impl khi chạy.

Điều này cho phép các ứng dụng của bên thứ ba sử dụng tiện ích mở rộng tự động tải thư viện của nhà cung cấp OEM. Thư viện OEM được đánh dấu là tùy chọn để ứ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 sử dụng tiện ích mở rộ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 ra thư viện đó.

Để 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, được yêu cầu bởi thẻ <uses-library> , sử dụng định dạng sau: /etc/permissions/ ANY_FILENAME .xml . Ví dụ: /etc/permissions/camera_extensions.xml . Các tệp trong thư mục này cung cấp ánh xạ của thư viện có tên trong <uses-library> tới đường dẫn tệp thực tế trên thiết bị.
  2. Sử dụng ví dụ dưới đây để thêm thông tin cần thiết vào tệp.

    • name phải là androidx.camera.extensions.impl vì đó là thư viện mà CameraX tìm kiếm.
    • file là đường dẫn tuyệt đối của tệp chứa phần triển khai tiện ích mở rộng (ví dụ: /system/framework/androidx.camera.extensions.impl.jar ảnh.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ợ tiện ích mở rộng CameraX phải đặt thuộc tính ro.camerax.extensions.enabled thành true để cho phép truy vấn xem thiết bị có hỗ trợ tiện ích mở rộng hay không. Để thực hiện việc này, hãy thêm dòng sau vào tệp tạo thiết bị:

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

Thẩm định

Để kiểm tra việc triển khai thư viện nhà cung cấp OEM của bạn 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/ , ứng dụng này chạy qua nhiều tiện ích mở rộng của nhà cung cấp khác nhau.

Sau khi bạn hoàn tất quá trình triển khai, hãy sử dụng Công cụ xác thực tiện ích mở rộng máy ảnh để chạy thử nghiệm tự động và thủ công nhằm xác minh rằng thư viện của nhà cung cấp được triển khai chính xác.

Chế độ cảnh mở rộng so với Tiện ích mở rộng máy ảnh

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

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

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

Chúng tôi khuyên bạn nên phơi sáng hiệu ứng mờ bằng cả chế độ cảnh mở rộng và Tiện ích mở rộng máy ảnh vì các ứng dụng có thể thích sử dụng một API cụ thể để bật hiệu ứng mờ. Chúng tôi khuyên bạn trước tiên nên sử dụng chế độ cảnh mở rộng vì đây là cách linh hoạt nhất để ứng dụng kích hoạt tính năng mở rộng hiệu ứng mờ. Sau đó, bạn có thể triển khai giao diện tiện ích mở rộng camera dựa trên chế độ cảnh mở rộng. Ví dụ: nếu việc triển khai hiệu ứng mờ trong máy ảnh HAL gặp khó khăn vì nó yêu cầu bộ xử lý hậu kỳ chạy trong lớp ứng dụng để xử lý hình ảnh, chúng tôi khuyên bạn nên triển khai tiện ích mở rộng hiệu ứng mờ bằng giao diện Tiện ích mở rộng của máy ảnh.

Các câu hỏi thường gặp (FAQ)

Có bất kỳ hạn chế nào về cấp độ API không?

Đúng. Điều này phụ thuộc vào bộ tính năng API Android được yêu cầu khi triển khai thư viện của nhà cung cấp OEM. Ví dụ: ExtenderStateListener.onPresetSession() sử dụng lệnh gọi SessionConfiguration.setSessionParameters() để đặt bộ thẻ cơ sở. Lệnh gọi này chỉ khả dụng trên API cấp 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 .