Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.

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

Các nhà sản xuất thiết bị có thể hiển thị các hiệu ứng đặc biệt như bokeh, 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 Camera2 và API tiện ích mở rộng CameraX để bật các hiệu ứng, được triển khai dưới dạng tiện ích mở rộng trong thư viện nhà cung cấp OEM trên thiết bị.

Để biết danh sách các tiện ích mở rộng được hỗ trợ, các tiện ích này 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 tại đây .

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ị.

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 giao diện extensions-interface : Ngành kiến ​​​​trúc

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

Như được minh họa 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 ứng dụng CameraX và Camera2 tương ứng sử dụng để truy cập vào 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 của nhà cung cấp OEM, hãy sao chép các tệp camera-extensions-stub vào một 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 tin camera-extensions-stub được chia thành các loại sau:

Tệp giao diện thiết yếu (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 bộ mở rộng Bokeh (triển khai nó nếu phần mở rộng Bokeh được hỗ trợ)

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

Các lớp bộ mở rộng ban đêm (triển khai nó nếu phần mở rộng Ban đêm được hỗ trợ)

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

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

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

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

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

Các lớp mở rộng Face Retouch (triển khai nó nếu phần mở rộng 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 triển khai cho mọi tiện ích mở rộng. Nếu bạn không triển khai một 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 ứ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 minh họa luồng end-to-end bằng cách sử dụng phần mở rộng Night làm ví dụ:

Dòng chính

Hình 2. Thực hiện mở rộng 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 OEM triển khai tương thích với các phiên bản hỗ trợ Camera2 / X.

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

    InitializerImpl có một phương thức init() khởi tạo thư viện của 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 của Extender.

  3. Khởi tạo các lớp của Trình mở rộng:

    Khởi tạo các lớp Extender cho phần mở rộng. Có hai loại Extender: Basic Extender và Advanced Extender. Bạn phải triển khai một loại Phần mở rộng cho tất cả các Phần mở rộng. Để biết thêm thông tin, hãy xem Bộ mở rộng cơ bản so với 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 Bộ mở rộng nhiều lần. Do đó, không thực hiện khởi tạo quá nặng trong hàm tạo hoặc lệnh gọi init() . Chỉ thực hiện công việc nặng nhọc 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ó khả dụng trên ID camera được chỉ định hay không thông qua phiên bản Extender.

  5. Khởi tạo Bộ mở rộng với thông tin máy ảnh:

    Camera2 / X gọi init() trên cá thể 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ị cho việc bật tiện ích mở rộng.

  7. Bậ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ó cung cấp một cơ chế để kết nối việc triển khai OEM vào đường dẫn Camera2 chẳng hạn như đưa các thông số yêu cầu chụp hoặc kích hoạt bộ xử lý bài đăng.

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

Các phần sau đây 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 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 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 phiên bản chính và phụ mới đượ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() với phiên bản extensions-interface được hỗ trợ. Sau đó, Camera2 / X sử dụng phiên bản do 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à khả năng mà nó sẽ gọi.

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 khác nhau giữa Camera2 / X và thư viện của nhà cung cấp, thì nó được coi là không tương thích và tiện ích mở rộng bị vô hiệu hóa.

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 với các phiên bản extensions-interface trước đó. Ví dụ: nếu Camera2 / X hỗ trợ extensions-interface 1.3.0, thì các 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 đả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

Khả năng tương thích chuyển tiếp với các thư viện của nhà cung cấp của 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 các tiện ích 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 trường hợp này, bạn có thể trả lại 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 các phiên bản Camera2 / X không được hỗ trợ, bạn có thể trả lại phiên bản không tương thích như 99.0.0 để tắt các 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 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 tới 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 quá trình khởi tạo hoàn tất.

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 triển khai extensions-interface : Trình mở rộng cơ bản và Trình mở rộng nâng cao. 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ý bài đăng 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 ảnh khi cần.

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

Bộ mở rộng cơ bản Phần 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 tồn tại bộ xử lý)
Chụp tĩnh: JPEG hoặc YUV_420_888 (nếu có bộ xử lý)
Có thể tùy chỉnh bởi OEM.
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ố cho 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 và gửi tất cả hình ảnh và kết quả chụp đến bộ xử lý. Một cá thể 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ả và Hình ảnh.

Camera2 / X gọi startRepeatingstartCapture trên SessionProcessorImpl để báo hiệu 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 dẫn máy ảnh
  • onPresetSession cung cấp các tham số phiên.
  • onEnableSession gửi một yêu cầu duy nhất ngay sau khi CameraCaptureSession được cấu hình.
  • onDisableSession gửi một yêu cầu trước khi đóng CameraCaptureSession .
  • 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 cấu hình.
  • onCaptureSessionEnd được gọi trước khi đóng CameraCaptureSession .
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 hiệu ứ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à 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, bạn phải triển khai đúng cách thư viện của nhà cung cấp để hỗ trợ các luồng 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 phần 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 còn lại của thông tin 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 (lifeecycleOwner, cameraSelector, preview, ...)

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ố nơi trong đường ống camera. Mỗi loại tiện ích mở rộng có các lớp Bộ mở rộng 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 mỗi tiện ích mở rộng:

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

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java

HdrImageCaptureExtenderImpl.java

Tự động AutoPreviewExtenderImpl.java

AutoImageCaptureExtenderImpl.java

Bokeh 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 trình giữ chỗ trong ví dụ sau. Thay thế chúng bằng tên của các tệp thực mà bạn đang triển khai.

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

  • Chèn các tham số phiên khi 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 và gửi một yêu cầu duy nhất để thông báo cho HAL với các tham số trả về ( onEnableSession , onDisableSession ).
  • Tiêm 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 trực tiếp gọi 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 phần mở rộng.

Đây thường là bước đầu tiên để các ứng dụng kiểm tra xem loại tiện ích mở rộng nhất định có được hỗ trợ cho một 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 máy ảnh 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, các ứng dụng nên truy vấn thông tin sau trước khi bật tiện ích mở rộng.

  • Phạm vi độ trễ chụp ảnh tĩnh: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange trả về phạm vi độ trễ chụp ảnh để ứng dụng đánh giá xem có phù hợp để bật tiện ích mở rộng cho tình huống hiện tại 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à các kích thước được hỗ trợ cho định dạng và kích thước bề mặt.

  • Các khóa yêu cầu và kết quả được hỗ trợ: Camera2 / X gọi các phương pháp sau để truy xuất các khóa yêu cầu chụp được hỗ trợ và khóa 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() đầu tiên trên các lớp Extender này trước khi truy vấn để biết thêm thông tin.

Luồng ứng dụng 3: Xem trước / chụp ảnh tĩnh có 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 của việc 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à máy ảnh HAL xử lý phần mở rộng.

Trong quy trình này, Camera2 / X trước tiên gọi init() sau đó là onInit , thông báo cho bạn rằng một 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 cao trong onInit() .

Khi cấu hình CameraCaptureSession , Camera2 / X gọi onPresetSession để lấy các tham số phiên. Sau khi phiên chụp được cấu hình thành công, Camera2 / X gọi onEnableSession trả về một cá thể CaptureStageImpl có chứa các thông số chụp. Camera2 / X ngay lập tức gửi một yêu cầu duy nhất với 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 với các thông 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() .

Xem trước bộ xử lý

Ngoài HAL 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 cá thể RequestUpdateProcessorImpl xử lý cá thể TotalCaptureResult và trả về một 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ả 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 vào bề mặt PRIVATE .

    Bạn cần triển khai và trả về một thể 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 đầu ra ở định dạng PRIVATE của bản xem trước. Camera2 / X sử dụng bề mặt YUV_420_888 thay vì PRIVATE để định cấu hình CameraCaptureSession để xem trước.

    Xem hình minh họa sau cho quy trình:

Bộ xử lý xem trước

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

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

  • onOutputSurface(Surface surface, int imageFormat) đặt bề mặt đầu ra cho bộ xử lý. Đối với PreviewImageProcessorImpl , imageFormat là một đị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, nó 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ề một phiên bản CaptureProcessorImpl bằ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 cá thể TotalCaptureResult và ghi kết quả đầu ra vào bề mặt YUV_420_888 .

Bạn có thể an toàn giả định 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 luồng trong sơ đồ dưới đây:

CaptureProcessor

Hình 7. Luồng chụp ảnh tĩnh với CaptureProcessorImpl

  1. Camera2 / X sử dụng bề mặt định dạng YUV_420_888 để chụp ảnh tĩnh để đị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 đầu ra YUV_420_888 .
  2. ImageCaptureExtenderImpl.getCaptureStages trả về danh sách CaptureStageImpl , trong đó mỗi phần tử ánh xạ tới một cá thể CaptureRequest với các thông số chụp được gửi bởi Camera2 / X. Ví dụ: nếu nó 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. Hình ảnh nhận được và các cá thể TotalCaptureResult được nhóm lại với nhau và được 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 được chỉ định bởi lệnh gọi onOutputSurface() . Camera2 / X chuyển đổi nó thành ảnh JPEG nếu cần.

Hỗ trợ nắm bắt các khóa và kết quả yêu cầu

Ngoài tính năng xem trước và chụp 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 thông 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à triển khai của bạn hỗ trợ:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() trả về các khóa yêu cầu chụp được hỗ trợ bởi triển khai của bạn.
  • 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ý phần 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 , đượ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 dưới đây 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ù 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 tiện ích mở rộng cơ bản triển khai 1.2.0 hoặc các phiên bản 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 trả về và chỉ hỗ trợ các phím có trong đó. Ví dụ: nếu bạn quyết định chỉ trả lại CaptureRequest#CONTROL_ZOOM_RATIOCaptureRequest#SCALER_CROP_REGION trong 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 flash và bù phơi sáng.

Phần 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 trong 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 một lớp bao bọc, hoặc một lớp trung gian, vì vậy bạn có thể tùy chỉnh cấu hình luồng và gửi các yêu cầu chụp theo yêu cầu.

Tệp để triển khai

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

Mở rộng các lớp để triển khai
Đêm advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
Tự động advanced/AutoAdvancedExtenderImpl.java
Bokeh 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ế nó 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 vẫn ước tính: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() trả về phạm vi độ trễ chụp ảnh để ứng dụng đánh giá xem có phù hợp để bật tiện ích mở rộng cho tình huống hiện tại hay không.

  • Các độ 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 một 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 một 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 pháp sau để truy xuất các khóa yêu cầu chụp được hỗ trợ và khóa 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ợ khóa yêu cầu chụp và kết quả .

Luồng ứng dụng 3: Xem trước / chụp ảnh tĩnh có 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 cho thấy quy trình chính để bắt đầu xem trước và vẫn chụp cho loại Trình mở rộng nâng cao. Hãy đi qua từng bước.

  1. 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 các yêu cầu chụp để bắt đầu xem trước và vẫn yêu cầu chụp. AdvancedExtenderImpl.createSessionProcessor() được gọi để trả về cá thể SessionProcessorImpl .

  2. initSession

    SessionProcessorImpl.initSession() khởi tạo phiên cho phần 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 thông 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 bề mặt, kích thước và định dạng 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 cá thể Camera2SessionConfigImpl , bao gồm danh sách các cá thể Camera2OutputConfigImpl và các tham số phiên được sử dụng để định cấu hình CameraCaptureSession . Bạn chịu trách nhiệm xuất hình ảnh máy ảnh chính xác ra bề mặt đầu ra do 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 camera 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 định cấu hình bề mặt đầu ra được cung cấp cho đường ống camera và cho phép camera HAL xử lý hình ảnh.
    • Xử lý bề mặt ImageReader trung gian (RAW, YUV, v.v.): Thêm bề mặt ImageReader trung gian vào CameraCaptureSession với một 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 chia sẻ bề mặt Camera2: Sử dụng chia sẻ bề mặt với bề mặt khác bằng cách thêm bất kỳ cá thể Camera2OutputConfigImpl nào vào phương thức getSurfaceSharingOutputConfigs() của một cá thể 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 đích và truy xuất hình ảnh từ ImageReaderOutputConfigImpl .

  3. onCaptureSessionStartRequestProcessorImpl

    Khi CameraCaptureSession khởi động và khuôn khổ Camera gọi onConfigured() , thì Camera2 / X gọi SessionProcessorImpl.onCaptureSessionStart() với trình bao bọc yêu cầu Camera2 RequestProcessImpl . Camera2 / X triển khai 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 ImageReaderOutputConfigImpl được sử dụng.

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

    • Bề mặt đích được chỉ định bởi ID của cá thể Camera2OutputConfigImpl .
    • Khả năng truy xuất hình ảnh của ImageReader .

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

    Cá thể 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

    Trong triển khai Advanced Extender, bạn có thể gửi yêu cầu chụp thông qua giao diện 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 trình tự chụp ảnh tĩnh bằng cách gọi SessionProcessorImpl#startRepeatingSessionProcessorImpl#startCapture . Bạn nên gửi các 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 các thông 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 các 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 các nhà phát triển đặt các khóa trong danh sách getAvailableCaptureRequestKeys , bạn phải kích hoạt các tham số và đảm bảo kết quả chụp có 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 như CaptureRequest.CONTROL_AF_TRIGGERCaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER . Bạn có thể bỏ qua bất kỳ khóa yêu cầu chụp nào 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 chạm để lấy nét và flash với 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 kết thúc, deInitSession() thực hiện 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 hiệu ứng cho ảnh tĩnh.

Đối với loại Basic Extender, bất kể bật hiệu ứng để xem trước, bạn phải triển khai cả ImageCaptureExtenderImplPreviewExtenderImpl cho một phần mở rộng nhất định. Often, an app also uses a YUV stream to analyze the image content such as finding QR codes or text. To better support this use case , you should support the stream combination of preview, still capture, and a YUV_420_888 stream for configuring CameraCaptureSession . This means that if you implement a processor, then you have to support the stream combination of three YUV_420_888 streams.

For Advanced Extender, Camera2/X passes three output surfaces to the SessionProcessorImpl.initSession() call. These output surfaces are for preview , still capture, and image analysis, respectively. You must ensure that preview and still capture output surfaces show the valid output. However, for the image analysis output surface, ensure it's working only when it's non-null. If your implementation can't support the image analysis stream, you can return an empty list in AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() . This ensures the image analysis output surface is always null in SessionProcessorImpl.initSession() .

Support video capture

The current Camera Extension architecture supports only the preview and still capture use cases. We don't support enabling the extension on the MediaCodec or MediaRecorder surfaces for recording the video. However, it's possible for apps to record the preview output.

Supporting MediaCodec and MediaRecorder surfaces is under investigation.

Extensions interface version history

The following table shows the Camera Extension interface version history. You should always implement the vendor library with the latest version.

Version Added features
1.0.0
  • Version verification
    • ExtensionVersionImpl
  • Basic Extender
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • Library initialization
    • InitializerImpl
  • Expose supported resolutions
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • Get estimated capture latency
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0
  • Expose supported capture request keys/results keys
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys and getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys and getAvailableCaptureResultKeys
    • New process() call that takes ProcessResultImpl in PreviewImageProcessorImpl and CaptureProcessorImpl
    • Support trigger type request
      • AdvancedExtenderImpl.startTrigger

Reference implementation

For a reference OEM vendor library implementation, see camera-testlib-extensions . Note that this implementation performs passthroughs without actually implementing the effects.

Set up the vendor library on a device

The OEM vendor library isn't built into an app; it's loaded from the device at runtime by Camera2/X. In CameraX, the <uses-library> tag declares that the androidx.camera.extensions.impl library, which is defined in the AndroidManifest.xml file of the camera-extensions library, is a dependency of CameraX and must be loaded at runtime. In Camera2, the framework loads an extensions service that also declares that the <uses-library> loads the same androidx.camera.extensions.impl library at runtime.

This allows third-party apps using extensions to automatically load the OEM vendor library. The OEM library is marked as optional so apps can run on devices that don't have the library on the device. Camera2/X handles this behavior automatically when an app tries to use a camera extension as long as the device manufacturer places the OEM library on the device so that it can be discovered by the app.

To set up the OEM library on a device, do the following:

  1. Add a permission file, which is required by the <uses-library> tag, using the following format: /etc/permissions/ ANY_FILENAME .xml . For example, /etc/permissions/camera_extensions.xml . The files in this directory provide a mapping of the library named in <uses-library> to the actual file path on the device.
  2. Use the example below to add the required information to the file.

    • name must be androidx.camera.extensions.impl as that's the library that CameraX searches for.
    • file is the absolute path of the file that contains the extensions implementation (for example, /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>
    

In Android 12 or higher, devices supporting CameraX extensions must have the ro.camerax.extensions.enabled property set to true , which allows for querying whether a device supports extensions. To do this, add the following line in the device make file:

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

Validation

To test your implementation of the OEM vendor library during the development stage, use the example app at androidx-main/camera/integration-tests/extensionstestapp/ , which runs through various vendor extensions.

After you complete your implementation, use the Camera Extensions Validation Tool to run automated and manual tests to verify that the vendor library is implemented correctly.

Extended scene mode versus Camera Extensions

For the bokeh effect, in addition to exposing it using Camera Extensions, you can expose the effect using the extended scene mode, which is enabled through the CONTROL_EXTENDED_SCENE_MODE key. For more implementation details, see Camera Bokeh .

Extended scene mode has fewer restrictions compared to Camera Extensions for camera2 apps. For example, you can enable extended scene mode in a regular CameraCaptureSession instance that supports flexible stream combinations and capture request parameters. In contrast, camera extensions support only a fixed set of stream types and have limited support for capture request parameters.

A downside of extended scene mode is that you can only implement it in the camera HAL, which means that it must be verified to work across all orthogonal controls available to app developers.

We recommend exposing bokeh using both the extended scene mode and Camera Extensions because apps might prefer to use a particular API to enable bokeh. We recommend first using the extended scene mode because this is the most flexible way for apps to enable the bokeh effect. Then you can implement the camera extensions interface based on the extended scene mode. If implementing bokeh in the camera HAL is difficult, for example, because it requires a post processor running in the app layer to process images, we recommend implementing the bokeh effect using the Camera Extensions interface.

Frequently asked questions (FAQs)

Are there any restrictions on API levels?

Yes. This depends on the Android API feature set that's required by the OEM vendor library implementation. For example, ExtenderStateListener.onPresetSession() uses the SessionConfiguration.setSessionParameters() call to set a baseline set of tags. This call is available only on API level 28 and higher. For details on specific interface methods, see the API reference documentation .