افزونه‌های دوربین

سازندگان دستگاه می‌توانند افزونه‌هایی مثل بوکه، حالت شب، و HDR را ازطریق میانای «افزونه‌های دوربین» که توسط کتابخانه فروشنده سازنده اصلی محصول ارائه می‌شود دراختیار توسعه‌دهندگان طرف سوم قرار دهند. توسعه‌دهندگان می‌توانند از Camera2 Extensions API و CameraX Extensions API برای دسترسی به افزونه‌های پیاده‌سازی‌شده در کتابخانه فروشنده OEM استفاده کنند.

برای مشاهده فهرست افزونه‌های پشتیبانی‌شده که در Camera2 و CameraX یکسان است، CameraX Extensions API را ببینید. اگر می‌خواهید افزونه‌ای اضافه کنید، گزارش اشکالی در Issue Tracker ثبت کنید.

این صفحه نحوه پیاده‌سازی و فعال کردن کتابخانه فروشنده سازنده اصلی محصول در دستگاه‌ها را شرح می‌دهد.

معماری

نمودار زیر معماری میانای «افزونه‌های دوربین» یا extensions-interface را توصیف می‌کند: معماری

شکل ۱. نمودار معماری «افزونه‌های دوربین»

همان‌طور که در نمودار نشان داده شده است، برای پشتیبانی از «افزونه‌های دوربین»، باید extensions-interface ارائه‌شده توسط کتابخانه فروشنده سازنده اصلی محصول را پیاده‌سازی کنید. کتابخانه فروشنده سازنده اصلی شما دو API را فعال می‌کند: CameraX Extensions API و Camera2 Extensions API، که به‌ترتیب توسط برنامه‌های CameraX و Camera2 برای دسترسی به افزونه‌های فروشنده استفاده می‌شوند.

پیاده‌سازی کتابخانه فروشنده سازنده اصلی محصول

برای پیاده‌سازی کتابخانه فروشنده سازنده تجهیزات اصلی، camera-extensions-stub فایل‌ها را در پروژه کتابخانه سیستم کپی کنید. این فایل‌ها میانای «افزونه‌های دوربین» را تعریف می‌کنند.

فایل‌های camera-extensions-stub به دسته‌های زیر تقسیم می‌شوند:

فایل‌های رابط ضروری (اصلاح نکنید)

  • 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

پیاده‌سازی‌های اجباری (پیاده‌سازی خودتان را اضافه کنید)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

کلاس‌های گسترش‌دهنده بوکه (اگر افزونه بوکه پشتیبانی می‌شود، آن را پیاده‌سازی کنید)

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

کلاس‌های توسعه‌دهنده شب (اگر «افزونه شب» پشتیبانی می‌شود، آن را پیاده‌سازی کنید)

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

کلاس‌های گسترش‌دهنده خودکار (اگر «افزونه خودکار» پشتیبانی می‌شود، آن را پیاده‌سازی کنید)

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

کلاس‌های توسعه‌دهنده HDR (اگر افزونه HDR پشتیبانی می‌شود، آن را پیاده‌سازی کنید)

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

کلاس‌های توسعه‌دهنده «رتوش چهره» (اگر افزونه «رتوش چهره» پشتیبانی می‌شود، آن را پیاده‌سازی کنید)

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

برنامه‌های کمکی (اختیاری، قابل‌حذف)

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

ملزم نیستید برای هر افزونه‌ای پیاده‌سازی ارائه دهید. اگر افزونه‌ای را پیاده‌سازی نمی‌کنید، isExtensionAvailable() را روی برگرداندن false تنظیم کنید یا کلاس‌های Extender مربوطه را بردارید. «میاناهای برنامه‌سازی کاربردی» Camera2 و «افزونه‌های CameraX» به برنامه گزارش می‌دهند که افزونه دردسترس نیست.

بیایید نحوه تعامل Camera2 و CameraX Extensions API با کتابخانه فروشنده را برای فعال کردن افزونه بررسی کنیم. نمودار زیر جریان سرتاسری را بااستفاده از افزونه Night به‌عنوان نمونه نشان می‌دهد:

Mainflow

شکل ۲. پیاده‌سازی افزونه شب

  1. درستی‌سنجی نسخه:

    ‫Camera2/X ExtensionVersionImpl.checkApiVersion() را فرا می‌خواند تا مطمئن شود نسخه extensions-interface پیاده‌سازی‌شده توسط سازنده تجهیزات اصلی با نسخه‌های پشتیبانی‌شده Camera2/X سازگار است.

  2. راه‌اندازی کتابخانه فروشنده:

    ‫InitializerImpl روش init() را دارد که کتابخانه فروشنده را مقداردهی اولیه می‌کند. ‫Camera2/X قبل‌از دسترسی به کلاس‌های «توسعه‌دهنده»، مقداردهی اولیه را تکمیل می‌کند.

  3. نمونه‌سازی کلاس‌های Extender:

    کلاس‌های «توسعه‌دهنده» را برای افزونه نمونه‌سازی می‌کند. دو نوع «افزونه» وجود دارد: «افزونه پایه» و «افزونه پیشرفته». باید یک نوع «گسترش‌دهنده» برای همه «افزونه‌ها» پیاده‌سازی کنید. برای اطلاعات بیشتر، به «گسترش‌دهنده پایه» دربرابر «گسترش‌دهنده پیشرفته» مراجعه کنید.

    ‫Camera2/X با کلاس‌های «توسعه‌دهنده» نمونه‌سازی و تعامل می‌کند تا اطلاعات را بازیابی کند و افزونه را فعال کند. برای افزونه‌ای معین، Camera2/X می‌تواند کلاس‌های «توسعه‌دهنده» را چندین بار نمونه‌سازی کند. در نتیجه، مقداردهی اولیه سنگین را در سازنده یا فراخوانی init() انجام ندهید. فقط زمانی که جلسه دوربین درحال شروع است، مثل زمانی که onInit() در «توسعه‌دهنده پایه» یا initSession() در «توسعه‌دهنده پیشرفته» فراخوانده می‌شود، کارهای سنگین را انجام دهید.

    برای افزونه Night، کلاس‌های Extender زیر برای نوع Basic Extender نمونه‌سازی می‌شوند:

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    و برای نوع «گسترش‌دهنده پیشرفته»:

    • NightAdvancedExtenderImpl.java
  4. بررسی دردسترس بودن افزونه:

    قبل‌از فعال کردن افزونه، isExtensionAvailable() بررسی می‌کند که آیا افزونه ازطریق نمونه «توسعه‌دهنده» در شناسه دوربین مشخص‌شده دردسترس است یا نه.

  5. راه‌اندازی «توسعه‌دهنده» با اطلاعات دوربین:

    ‫Camera2/X با init() در نمونه Extender تماس می‌گیرد و شناسه دوربین و CameraCharacteristics را به آن ارسال می‌کند.

  6. اطلاعات پُرسمان:

    کلاس Extender را برای بازیابی اطلاعاتی مثل وضوح‌های پشتیبانی‌شده، تأخیر تخمینی ثبت عکس، و کلیدهای درخواست ثبت از Extender فراخوانی می‌کند تا برای فعال کردن افزونه آماده شود.

  7. فعال کردن افزونه در «افزونه»:

    کلاس Extender همه میاناهای لازم برای فعال کردن کلاس را ارائه می‌دهد. این ویژگی سازوکاری برای متصل کردن پیاده‌سازی OEM به خط لوله Camera2 ارائه می‌دهد، مانند تزریق پارامترهای درخواست ضبط یا فعال کردن پس‌پردازنده.

    برای نوع «گسترش‌دهنده پیشرفته»، Camera2/X با SessionProcessorImpl تعامل می‌کند تا افزونه را فعال کند. Camera2/X با فراخوانی createSessionProcessor() در Extender، نمونه SessionProcessorImpl را بازیابی می‌کند.

بخش‌های زیر جریان افزونه را با جزئیات بیشتری شرح می‌دهند.

درستی‌سنجی نسخه

هنگام بار کردن کتابخانه فروشنده OEM از دستگاه در زمان اجرا، Camera2/X بررسی می‌کند که آیا کتابخانه با نسخه extensions-interface سازگار است یا نه. extensions-interface از نسخه‌بندی معنایی یا MAJOR.MINOR.PATCH (اصلی.فرعی.وصله) استفاده می‌کند، برای مثال، ۱.۱.۰ یا ۱.۲.۰. بااین‌حال، فقط از نسخه‌های اصلی و فرعی در درستی‌سنجی نسخه استفاده می‌شود.

برای درستی‌سنجی نسخه، Camera2/X با نسخه پشتیبانی‌شده ExtensionVersionImpl.checkApiVersion() extensions-interface تماس می‌گیرد. سپس Camera2/X از نسخه گزارش‌شده توسط کتابخانه OEM برای تعیین اینکه آیا افزونه می‌تواند فعال شود و چه قابلیت‌هایی باید فراخوانی کند، استفاده می‌کند.

سازگاری نسخه اصلی

اگر نسخه‌های اصلی رابط افزونه بین Camera2/X و کتابخانه فروشنده متفاوت باشد، ناسازگار درنظر گرفته می‌شود و افزونه غیرفعال می‌شود.

سازگاری با نسخه قدیمی

تا زمانی که نسخه اصلی یکسان باشد، Camera2/X سازگاری با نسخه‌های قبلی کتابخانه‌های فروشنده سازنده تجهیزات اصلی را که با نسخه‌های extensions-interface قبلی ساخته شده‌اند تضمین می‌کند. برای مثال، اگر Camera2/X از extensions-interface 1.3.0 پشتیبانی کند، کتابخانه‌های فروشنده سازنده تجهیزات اصلی که 1.0.0، 1.1.0، و 1.2.0 را پیاده‌سازی کرده‌اند همچنان سازگار هستند. این همچنین به این معنی است که پس‌از پیاده‌سازی نسخه خاصی از کتابخانه فروشنده، Camera2/X مطمئن می‌شود که کتابخانه با نسخه‌های آتی extension-interface سازگار با نسخه قدیمی باشد.

سازگاری با نسخه جدید

سازگاری پیش‌رو با کتابخانه‌های فروشنده extensions-interface جدیدتر به شما، سازنده تجهیزات اصلی، بستگی دارد. اگر برای پیاده‌سازی افزونه‌ها به برخی‌از ویژگی‌ها نیاز دارید، شاید بخواهید افزونه‌ها را از نسخه خاصی فعال کنید. در این مورد، وقتی نسخه کتابخانه Camera2/X الزامات را برآورده می‌کند، می‌توانید نسخه پشتیبانی‌شده extensions-interface را برگردانید. اگر نسخه‌های Camera2/X پشتیبانی نمی‌شوند، می‌توانید نسخه ناسازگاری مثل 99.0.0 را برگردانید تا افزونه‌ها غیرفعال شوند.

مقداردهی اولیه کتابخانه فروشنده

پس‌از درستی‌سنجی نسخه extensions-interface پیاده‌سازی‌شده توسط کتابخانه OEM،‏ Camera2/X فرایند مقداردهی اولیه را شروع می‌کند. روش InitializerImpl.init() به کتابخانه سازنده تجهیزات اصلی (OEM) اطلاع می‌دهد که برنامه‌ای درحال تلاش برای استفاده از افزونه‌ها است.

‫Camera2/X تا زمانی که کتابخانه فروشنده «سازنده اصلی محصول» OnExtensionsInitializedCallback.onSuccess() را برای اطلاع‌رسانی درباره تکمیل مقداردهی اولیه فراخوانی نکند، هیچ فراخوانی دیگری به کتابخانه «سازنده اصلی محصول» انجام نمی‌دهد (به‌جز بررسی نسخه).

باید InitializerImpl را از extensions-interface نسخه ۱.۱.۰ پیاده‌سازی کنید. اگر کتابخانه فروشنده «سازنده اصلی محصول» extensions-interface 1.0.0 را پیاده‌سازی کند، Camera2/X از مرحله راه‌اندازی کتابخانه رد می‌شود.

مقایسه «توسعه‌دهنده پایه» با «توسعه‌دهنده پیشرفته»

دو نوع پیاده‌سازی extensions-interface وجود دارد: «گسترش‌دهنده پایه» و «گسترش‌دهنده پیشرفته». «افزونه پیشرفته» از نسخه extensions-interface 1.2.0 پشتیبانی می‌شود.

«افزونه پایه» را برای افزونه‌هایی پیاده‌سازی کنید که تصاویر را در HAL دوربین پردازش می‌کنند یا از پس‌پردازنده‌ای استفاده می‌کنند که قادر به پردازش جاری‌سازی‌های YUV است.

«گسترش‌دهنده پیشرفته» را برای افزونه‌هایی که باید پیکربندی جاری‌سازی Camera2 را سفارشی‌سازی کنند و درخواست‌های ضبط را درصورت نیاز ارسال کنند پیاده‌سازی کنید.

برای مقایسه، جدول زیر را ببینید:

توسعه‌دهنده پایه Advanced Extender
پیکربندی‌های جاری‌سازی ثابت
پیش‌نمایش: PRIVATE یا YUV_420_888 (اگر پردازنده وجود داشته باشد)
ضبط ثابت: JPEG یا YUV_420_888 (اگر پردازنده وجود داشته باشد)
سازنده اصلی محصول می‌تواند آن را سفارشی‌سازی کند.
درحال ارسال درخواست ضبط فقط Camera2/X می‌تواند درخواست‌های ضبط ارسال کند. می‌توانید پارامترهای این درخواست‌ها را تنظیم کنید. وقتی پردازنده برای ضبط تصویر ارائه می‌شود، Camera2/X می‌تواند چندین درخواست ضبط ارسال کند و همه تصاویر و نتایج ضبط را به پردازنده ارسال کند. یک نمونه RequestProcessorImpl برای شما فراهم شده است تا درخواست ضبط camera2 را اجرا کنید و نتایج و تصویر را دریافت کنید.

Camera2/X‏ startRepeating و startCapture را در SessionProcessorImpl فراخوانی می‌کند تا به سازنده اصلی سیگنال دهد که به‌ترتیب درخواست تکرار برای پیش‌نمایش و توالی ضبط عکس را شروع کند.

قلاب‌ها در خط لوله دوربین
  • ‫onPresetSession پارامترهای جلسه را ارائه می‌دهد.
  • onEnableSession بلافاصله پس‌از پیکربندی CameraCaptureSession، یک درخواست ارسال می‌کند.
  • ‫onDisableSession قبل‌از بسته شدن CameraCaptureSession یک درخواست واحد ارسال می‌کند.
  • initSession پیکربندی جلسه camera2 سفارشی‌شده را برای ایجاد جلسه ضبط مقداردهی اولیه می‌کند و برمی‌گرداند.
  • onCaptureSessionStart بلافاصله پس‌از پیکربندی CameraCaptureSession فراخوانی می‌شود.
  • ‫onCaptureSessionEnd قبل‌از بسته شدن CameraCaptureSession فراخوانی می‌شود.
مناسب برای افزونه‌های پیاده‌سازی‌شده در HAL دوربین یا در پردازنده‌ای که تصاویر YUV را پردازش می‌کند.
  • پیاده‌سازی‌های مبتنی بر Camera2 برای افزونه‌ها دارد.
  • به پیکربندی جاری‌سازی سفارشی مثل جاری‌سازی RAW نیاز دارد.
  • به توالی ضبط تعاملی نیاز دارد.
نسخه پشتیبانی‌شده میانای برنامه‌سازی کاربردی افزونه‌های Camera2: ‏Android نسخه ۱۳ یا بالاتر
افزونه‌های CameraX: ‏camera-extensions نسخه ۱.۱.۰ یا بالاتر
افزونه‌های Camera2: Android 12L یا بالاتر
افزونه‌های CameraX: camera-extensions 1.2.0-alpha03 یا بالاتر

جریان‌های برنامه

جدول زیر سه نوع جریان برنامه و فراخوانی‌های Camera Extensions API مربوط به آن‌ها را نشان می‌دهد. درحالی‌که Camera2/X این میاناهای برنامه‌سازی کاربردی را ارائه می‌دهد، باید کتابخانه فروشنده را به‌درستی پیاده‌سازی کنید تا از این جریان‌ها پشتیبانی کند. در بخش بعدی این موضوع را با جزئیات بیشتری شرح می‌دهیم.

افزونه‌های Camera2 افزونه‌های CameraX
دردسترس بودن افزونه پُرسمان CameraExtensionCharacteristics .getSupportedExtensions ExtensionsManager. isExtensionAvailable
اطلاعات پُرسمان CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

‫CameraX بقیه اطلاعات را در کتابخانه مدیریت می‌کند.

پیش‌نمایش و ضبط تصویر ثابت با فعال بودن افزونه CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector

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

توسعه‌دهنده پایه

میانای «توسعه‌دهنده پایه» قلاب‌هایی را در چندین مکان از خط لوله دوربین ارائه می‌دهد. هر نوع افزونه دارای کلاس‌های «توسعه‌دهنده» مربوطه است که «تولیدکنندگان تجهیزات اصلی» باید آن‌ها را پیاده‌سازی کنند.

جدول زیر کلاس‌های «افزونه» را که OEMها باید برای هر افزونه پیاده‌سازی کنند فهرست می‌کند:

کلاس‌های توسعه‌دهنده برای پیاده‌سازی
شب NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

HDR HdrPreviewExtenderImpl.java

HdrImageCaptureExtenderImpl.java

خودکار AutoPreviewExtenderImpl.java

AutoImageCaptureExtenderImpl.java

بوکه BokehPreviewExtenderImpl.java

BokehImageCaptureExtenderImpl.java

رتوش چهره BeautyPreviewExtenderImpl.java

BeautyImageCaptureExtenderImpl.java

در مثال زیر، از PreviewExtenderImpl و ImageCaptureExtenderImpl به‌عنوان جای‌بان استفاده می‌کنیم. این‌ها را با نام‌های فایل‌های واقعی که پیاده‌سازی می‌کنید جایگزین کنید.

«توسعه‌دهنده پایه» قابلیت‌های زیر را دارد:

  • هنگام پیکربندی CameraCaptureSession ( onPresetSession)، پارامترهای جلسه را تزریق کنید.
  • رویدادهای شروع و بستن جلسه ضبط را به شما اطلاع می‌دهد و یک درخواست واحد برای اطلاع دادن به HAL با پارامترهای برگشتی (onEnableSession، onDisableSession) ارسال می‌کند.
  • پارامترهای ضبط را برای درخواست تزریق کنید (PreviewExtenderImpl.getCaptureStage، ImageCaptureExtenderImpl.getCaptureStages).
  • پردازشگرهایی را برای پیش‌نمایش و ضبط تصویر ثابت اضافه کنید که بتواند جریان YUV_420_888 را پردازش کند.

بیایید ببینیم Camera2/X چگونه extensions-interface را فرا می‌خواند تا سه جریان برنامه ذکرشده در بالا را انجام دهد.

جریان برنامه ۱: بررسی دردسترس بودن افزونه

BasicExtenderAppFlow1

شکل ۳. جریان برنامه ۱ در «توسعه‌دهنده پایه»

در این جریان، Camera2/X مستقیماً روش isExtensionAvailable() را برای PreviewExtenderImpl و ImageCaptureExtenderImpl بدون فراخوانی init() فراخوانی می‌کند. هر دو کلاس «توسعه‌دهنده» باید true را برگردانند تا افزونه‌ها فعال شوند.

این اغلب اولین گام برای برنامه‌ها است تا قبل‌از فعال کردن افزونه، بررسی کنند که آیا نوع افزونه داده‌شده برای شناسه دوربین داده‌شده پشتیبانی می‌شود یا نه. دلیل آن این است که برخی‌از افزونه‌ها فقط در شناسه‌های دوربین خاصی پشتیبانی می‌شوند.

جریان برنامه ۲: اطلاعات پُرسمان

BasicExtenderAppFlow2

شکل ۴. جریان برنامه ۲ در «گسترش‌دهنده پایه»

پس‌از تعیین اینکه افزونه دردسترس است یا نه، برنامه‌ها باید اطلاعات زیر را قبل‌از فعال کردن افزونه جستجو کنند.

  • محدوده تأخیر همچنان ضبط می‌کند: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange محدوده تأخیر ضبط را برمی‌گرداند تا برنامه ارزیابی کند که آیا فعال کردن افزونه برای سناریو فعلی مناسب است یا نه.

  • اندازه‌های پشتیبانی‌شده برای سطح پیش‌نمایش و ضبط: ImageCaptureExtenderImpl.getSupportedResolutions و PreviewExtenderImpl.getSupportedResolutions فهرستی از قالب‌های تصویر و اندازه‌هایی را که برای قالب و اندازه سطح پشتیبانی می‌شوند برمی‌گردانند.

  • کلیدهای درخواست و نتیجه پشتیبانی‌شده: ‫Camera2/X روش‌های زیر را برای بازیابی کلیدهای درخواست و نتیجه ضبط پشتیبانی‌شده از پیاده‌سازی شما فرا می‌خواند:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

‫Camera2/X همیشه ابتدا init() را در این کلاس‌های «توسعه‌دهنده» فرا می‌خواند و سپس برای اطلاعات بیشتر پُرسمان می‌کند.

جریان برنامه ۳: پیش‌نمایش/ضبط تصویر ثابت با فعال بودن افزونه (پیاده‌سازی HAL)

BasicExtenderAppFlow3

شکل ۵. جریان برنامه ۳ در «گسترش‌دهنده پایه»

نمودار بالا جریان اصلی فعال‌سازی پیش‌نمایش و ضبط تصویر ثابت با افزونه بدون پردازنده را نشان می‌دهد. این یعنی HAL دوربین افزونه را پردازش می‌کند.

در این جریان، ابتدا Camera2/X با init() و سپس با onInit تماس می‌گیرد، که به شما اطلاع می‌دهد جلسه دوربین با افزونه‌های مشخص‌شده به‌زودی شروع می‌شود. می‌توانید مقداردهی اولیه سنگین را در onInit() انجام دهید.

هنگام پیکربندی CameraCaptureSession، Camera2/X برای دریافت پارامترهای جلسه onPresetSession را فرا می‌خواند. پس‌از اینکه جلسه ضبط باموفقیت پیکربندی شد، Camera2/X‏ onEnableSession را فرا می‌خواند و نمونه‌ای از CaptureStageImpl برمی‌گرداند که حاوی پارامترهای ضبط است. ‫Camera2/X بلافاصله یک درخواست واحد با این پارامترهای ضبط برای اطلاع‌رسانی به لایه انتزاع سخت‌افزار ارسال می‌کند. به‌همین ترتیب، قبل‌از بسته شدن جلسه ضبط، Camera2/X onDisableSession را فرا می‌خواند و سپس یک درخواست واحد با پارامترهای ضبط برگشتی ارسال می‌کند.

درخواست تکرارشونده‌ای که Camera2/X راه‌اندازی کرده است حاوی پارامترهای درخواستی است که PreviewExtenderImpl.getCaptureStage() برگردانده است. علاوه‌براین، درخواست ضبط تصویر ثابت حاوی پارامترهای برگشتی از ImageCaptureExtenderImpl.getCaptureStages() است.

درنهایت، Camera2/X پس‌از پایان جلسه دوربین، onDeInit() را فراخوانی می‌کند. می‌توانید منابع را در onDeinit() آزاد کنید.

پردازنده پیش‌نمایش

علاوه‌بر HAL دوربین، می‌توانید افزونه‌ها را در پردازنده نیز پیاده‌سازی کنید.

PreviewExtenderImpl.getProcessorType را برای مشخص کردن نوع پردازنده همان‌طور که در زیر توضیح داده شده است پیاده‌سازی کنید:

  • PROCESSOR_TYPE_NONE: پردازنده‌ای وجود ندارد. تصاویر در HAL دوربین پردازش می‌شوند.

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY: نوع پردازنده به شما امکان می‌دهد درخواست تکرارشونده را با پارامترهای درخواست ضبط جدید براساس آخرین TotalCaptureResult به‌روز کنید.

    PreviewExtenderImpl.getProcessor باید یک نمونه RequestUpdateProcessorImpl برگرداند که نمونه TotalCaptureResult را پردازش کند و یک نمونه CaptureStageImpl برگرداند تا درخواست تکرارشونده را به‌روز کند. PreviewExtenderImpl.getCaptureStage() باید نتیجه پردازش را نیز منعکس کند و جدیدترین CaptureStageImpl را برگرداند.

  • ‫PROCESSOR_TYPE_IMAGE_PROCESSOR: این نوع به شما امکان می‌دهد تا پردازنده‌ای را برای پردازش تصاویر YUV_420_888 پیاده‌سازی کنید و برونداد را در سطح PRIVATE بنویسید.

    باید نمونه‌ای از PreviewImageProcessorImpl را در PreviewExtenderImpl.getProcessor پیاده‌سازی و برگردانید. پردازنده مسئول پردازش YUV_420_888 تصویر ورودی است. باید برونداد را در قالب PRIVATE پیش‌نمایش بنویسد. ‫Camera2/X به‌جای PRIVATE از سطح YUV_420_888 برای پیکربندی CameraCaptureSession برای پیش‌نمایش استفاده می‌کند.

    جریان را در تصویر زیر ببینید:

PreviewProcessor

شکل ۶. پیش‌نمایش جریان با PreviewImageProcessorImpl

میانای PreviewImageProcessorImpl ProcessImpl را گسترش می‌دهد و سه روش مهم دارد:

  • onOutputSurface(Surface surface, int imageFormat) سطح برونداد را برای پردازنده تنظیم می‌کند. برای PreviewImageProcessorImpl، imageFormat قالب پیکسل است، مثل PixelFormat.RGBA_8888.

  • onResolutionUpdate(Size size) اندازه تصویر ورودی را تنظیم می‌کند.

  • onImageFormatUpdate(int imageFormat) قالب تصویر ورودی را تنظیم می‌کند. درحال‌حاضر، فقط می‌تواند YUV_420_888 باشد.

پردازنده ضبط تصویر

برای ضبط تصویر ثابت، می‌توانید با برگرداندن نمونه‌ای از CaptureProcessorImpl بااستفاده از ImageCaptureExtenderImpl.getCaptureProcessor، پردازنده‌ای پیاده‌سازی کنید. پردازنده مسئول پردازش فهرست تصاویر YUV_420_888 و نمونه‌های TotalCaptureResult ضبط‌شده و نوشتن برونداد در سطح YUV_420_888 است.

می‌توانید با اطمینان فرض کنید که پیش‌نمایش قبل‌از ارسال درخواست عکس ثابت فعال و درحال اجرا است.

جریان را در نمودار زیر ببینید:

CaptureProcessor

شکل ۷. جریان ضبط با CaptureProcessorImpl همچنان ادامه دارد

  1. ‫Camera2/X از سطح قالب YUV_420_888 برای گرفتن عکس استفاده می‌کند تا جلسه گرفتن عکس را پیکربندی کند. Camera2/X با فراخوانی موارد زیر CaptureProcessorImpl را آماده می‌کند:

    • ‫CaptureProcessorImpl.onImageFormatUpdate() با YUV_420_888.
    • CaptureProcessorImpl.onResolutionUpdate() با اندازه تصویر ورودی.
    • CaptureProcessorImpl.onOutputSurface() با سطح YUV_420_888 برونداد.
  2. ‫ImageCaptureExtenderImpl.getCaptureStages فهرستی از CaptureStageImpl را برمی‌گرداند که در آن هر عنصر به یک نمونه CaptureRequest با پارامترهای ضبط که توسط Camera2/X ارسال شده‌اند نگاشت می‌شود. برای مثال، اگر فهرستی از سه نمونه CaptureStageImpl برگرداند، Camera2/X سه درخواست ضبط با پارامترهای ضبط مربوطه بااستفاده از API captureBurst ارسال می‌کند.

  3. تصاویر دریافتی و نمونه‌های TotalCaptureResult باهم بسته‌بندی می‌شوند و برای پردازش به CaptureProcessorImpl ارسال می‌شوند.

  4. CaptureProcessorImpl «تصویر» نتیجه (قالب YUV_420_888) را در سطح برونداد مشخص‌شده با فراخوانی onOutputSurface() می‌نویسد. Camera2/X درصورت لزوم آن را به تصاویر JPEG تبدیل می‌کند.

پشتیبانی از کلیدها و نتایج درخواست ضبط

علاوه‌بر پیش‌نمایش و ضبط دوربین، برنامه‌ها می‌توانند پارامترهای فلاش یا بزرگ‌نمایی را تنظیم کنند یا روی تک‌ضرب برای فوکوس کردن راه‌اندازی کنند. ممکن است این پارامترها با پیاده‌سازی افزونه شما سازگار نباشد.

روش‌های زیر به extensions-interface نسخه ۱.۳.۰ اضافه شده است تا به شما امکان دهد پارامترهایی را که پیاده‌سازی‌تان پشتیبانی می‌کند نمایان کنید:

  • ‫ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() کلیدهای درخواست ضبط پشتیبانی‌شده توسط پیاده‌سازی شما را برمی‌گرداند.
  • ‫ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() کلیدهای نتیجه ضبط را که در نتیجه ضبط وجود دارد برمی‌گرداند.

اگر HAL دوربین افزونه را پردازش کند، Camera2/X نتایج ضبط را در CameraCaptureSession.CaptureCallback بازیابی می‌کند. اما اگر پردازنده پیاده‌سازی شده باشد، Camera2/X نتایج ضبط را در ProcessResultImpl بازیابی می‌کند که به روش process() در PreviewImageProcessorImpl و CaptureProcessorImpl ارسال می‌شود. مسئولیت گزارش نتیجه ضبط ازطریق ProcessResultImpl به Camera2/X برعهده شما است.

به‌عنوان مثال، تعریف رابط CaptureProcessorImpl را در زیر ببینید. در extensions-interface نسخه ۱.۳.۰ یا بالاتر، تماس process() دوم فراخوانده می‌شود:

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);
}

برای عملیات رایج دوربین مثل بزرگ‌نمایی، تک‌ضرب برای فوکوس، فلاش، و جبران نوردهی، توصیه می‌کنیم از کلیدهای زیر برای هم درخواست ضبط و هم نتیجه ضبط پشتیبانی کنید:

  • بزرگ‌نمایی:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • تک‌ضرب برای فوکوس:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Flash:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • جبران نوردهی:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

برای «افزونه‌های پایه» که نسخه ۱.۲.۰ یا نسخه‌های قبلی را پیاده‌سازی می‌کنند، CameraX Extensions API به‌طور صریح از همه کلیدهای بالا پشتیبانی می‌کند. برای extensions-interface 1.3.0، هم CameraX و هم Camera2 از فهرست برگردانده‌شده پیروی می‌کنند و فقط از کلیدهای موجود در آن پشتیبانی می‌کنند. برای مثال، اگر تصمیم بگیرید فقط CaptureRequest#CONTROL_ZOOM_RATIO و CaptureRequest#SCALER_CROP_REGION را در پیاده‌سازی نسخه ۱.۳.۰ برگردانید، این یعنی فقط بزرگ‌نمایی برای برنامه پشتیبانی می‌شود و ضربه برای فوکوس، فلاش، و جبران نوردهی مجاز نیست.

Advanced Extender

«گسترش‌دهنده پیشرفته» نوعی پیاده‌سازی فروشنده براساس Camera2 API است. این نوع Extender در extensions-interface نسخه ۱.۲.۰ اضافه شد. بسته به سازنده دستگاه، افزونه‌ها ممکن است در لایه برنامه پیاده‌سازی شوند که به عوامل زیر بستگی دارد:

  • پیکربندی جاری‌سازی سفارشی: جاری‌سازی‌های سفارشی مثل جاری‌سازی RAW را پیکربندی کنید یا برای شناسه‌های دوربین فیزیکی مختلف، چندین جاری‌سازی داشته باشید.

  • قابلیت ارسال درخواست‌های Camera2: از منطق تعامل پیچیده‌ای که می‌تواند درخواست‌های ضبط را با پارامترهای مبتنی بر نتایج درخواست‌های قبلی ارسال کند پشتیبانی می‌کند.

«توسعه‌دهنده پیشرفته» یک بسته‌بندی یا لایه میانی ارائه می‌دهد تا بتوانید پیکربندی جاری‌سازی را سفارشی‌سازی کنید و درخواست‌های ضبط را به‌صورت درخواستی ارسال کنید.

فایل‌های قابل اجرا

برای رفتن به پیاده‌سازی «توسعه‌دهنده پیشرفته»، روش isAdvancedExtenderImplemented() در ExtensionVersionImpl باید true را برگرداند. برای هر نوع افزونه، سازندگان تجهیزات اصلی باید کلاس‌های «گسترش‌دهنده» مربوطه را پیاده‌سازی کنند. فایل‌های پیاده‌سازی «توسعه‌دهنده پیشرفته» در بسته پیشرفته است.

کلاس‌های Extender برای پیاده‌سازی
شب advanced/NightAdvancedExtenderImpl.java
HDR advanced/HdrAdvancedExtenderImpl.java
خودکار advanced/AutoAdvancedExtenderImpl.java
بوکه advanced/BokehAdvancedExtenderImpl.java
رتوش چهره advanced/BeautyAdvancedExtenderImpl.java

در مثال زیر، از AdvancedExtenderImpl به‌عنوان جای‌بان استفاده می‌کنیم. آن را با نام فایل «توسعه‌دهنده» برای افزونه‌ای که پیاده‌سازی می‌کنید جایگزین کنید.

ببینیم Camera2/X چگونه extensions-interface را برای دستیابی به سه جریان برنامه فرا می‌خواند.

جریان برنامه ۱: بررسی دردسترس بودن افزونه‌ها

AdvancedAppFlow1

شکل ۸. جریان برنامه ۱ در «توسعه‌دهنده پیشرفته»

ابتدا، برنامه بررسی می‌کند که آیا از افزونه داده‌شده پشتیبانی می‌شود یا نه.

جریان برنامه ۲: اطلاعات پُرسمان

AdvancedAppFlow2

شکل ۹. جریان برنامه ۲ در «توسعه‌دهنده پیشرفته»

پس‌از فراخواندن AdvancedExtenderImpl.init()، برنامه می‌تواند اطلاعات زیر را درباره AdvancedExtenderImpl پُرسمان کند:

  • تأخیر تخمینی در گرفتن عکس ثابت: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() محدوده تأخیر در گرفتن عکس ثابت را برمی‌گرداند تا برنامه ارزیابی کند که آیا فعال کردن افزونه برای سناریو فعلی مناسب است یا نه.

  • وضوح‌های پشتیبانی‌شده برای پیش‌نمایش و ضبط تصویر ثابت:

    • ‫AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() نقشه‌ای از قالب تصویر را به فهرست اندازه‌هایی که برای قالب و اندازه سطح پیش‌نمایش پشتیبانی می‌شوند برمی‌گرداند. تولیدکنندگان تجهیزات اصلی باید حداقل از قالب PRIVATE پشتیبانی کنند.

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() قالب و اندازه‌های پشتیبانی‌شده را برای سطح ضبط ثابت برمی‌گرداند. سازندگان اصلی محصول باید از هر دو برونداد قالب JPEG و YUV_420_888 پشتیبانی کنند.

    • ‫AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() اندازه‌های پشتیبانی‌شده برای جاری‌سازی اضافی YUV_420_888 برای تجزیه‌وتحلیل تصویر را برمی‌گرداند. اگر سطح YUV تجزیه‌وتحلیل تصویر پشتیبانی نشود، getSupportedYuvAnalysisResolutions() باید null یا فهرست خالی را برگرداند.

  • کلیدها/نتایج درخواست ضبط دردسترس (در extensions-interface 1.3.0 اضافه شده است): ‫Camera2/X روش‌های زیر را برای بازیابی کلیدهای درخواست ضبط پشتیبانی‌شده و کلیدهای نتیجه از پیاده‌سازی شما فرا می‌خواند:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

برای اطلاعات بیشتر، به پشتیبانی از کلیدهای درخواست و نتایج ضبط مراجعه کنید.

جریان برنامه ۳: پیش‌نمایش/ضبط عکس با افزونه فعال‌شده

AdvancedAppFlow3

شکل ۱۰. جریان برنامه ۳ در «تقویت‌کننده پیشرفته»

نمودار بالا جریان اصلی را برای شروع پیش‌نمایش و ضبط عکس برای نوع «توسعه‌دهنده پیشرفته» نشان می‌دهد. بیایید هر مرحله را با هم مرور کنیم.

  1. SessionProcessorImpl نمونه

    پیاده‌سازی اصلی «توسعه‌دهنده پیشرفته» در SessionProcessorImpl است که مسئول ارائه پیکربندی جلسه سفارشی و ارسال درخواست‌های ضبط برای شروع پیش‌نمایش و درخواست ضبط تصویر ثابت است. ‫AdvancedExtenderImpl.createSessionProcessor() برای برگرداندن نمونه SessionProcessorImpl فراخوانده می‌شود.

  2. initSession

    ‫SessionProcessorImpl.initSession() جلسه را برای افزونه مقداردهی اولیه می‌کند. در اینجا منابع را تخصیص می‌دهید و پیکربندی جلسه را برای آماده کردن CameraCaptureSession برمی‌گردانید.

    برای پارامترهای ورودی، Camera2/X پیکربندی‌های سطح خروجی را برای پیش‌نمایش، ضبط تصویر ثابت، و تجزیه‌وتحلیل اختیاری تصویر YUV مشخص می‌کند. این پیکربندی سطح خروجی (OutputSurfaceImpl) حاوی سطح، اندازه، و قالب تصویری است که با روش‌های زیر در AdvancedExtenderImpl بازیابی می‌شود:

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

    باید نمونه Camera2SessionConfigImpl برگردانید که شامل فهرستی از نمونه‌های Camera2OutputConfigImpl و پارامترهای جلسه‌ای است که برای پیکربندی CameraCaptureSession استفاده می‌شود. شما مسئول هستید که تصاویر صحیح دوربین را به سطوح خروجی که توسط Camera2/X ارسال شده‌اند، خروجی دهید. در اینجا چند گزینه برای فعال کردن برونداد ارائه شده است:

    • پردازش در HAL دوربین: می‌توانید سطوح برونداد را مستقیماً با پیاده‌سازی SurfaceOutputConfigImpl به CameraCaptureSession اضافه کنید. این کار سطح خروجی ارائه‌شده را برای خط لوله دوربین پیکربندی می‌کند و به HAL دوربین اجازه می‌دهد تصویر را پردازش کند.
    • پردازش سطح میانی ImageReader (RAW،‏ YUV، و غیره): سطوح میانی ImageReader را با نمونه ImageReaderOutputConfigImpl به CameraCaptureSession اضافه کنید.

      باید تصاویر واسط را پردازش کنید و تصویر نتیجه را در سطح برونداد بنویسید.

    • استفاده از هم‌رسانی سطح Camera2: با افزودن هر نمونه Camera2OutputConfigImpl به روش getSurfaceSharingOutputConfigs() نمونه Camera2OutputConfigImpl دیگر، از هم‌رسانی سطح با سطح دیگر استفاده کنید. قالب و اندازه سطح باید یکسان باشد.

    همه Camera2OutputConfigImpl ازجمله SurfaceOutputConfigImplو ImageReaderOutputConfigImpl باید شناسه یکتایی (getId()) داشته باشند که برای مشخص کردن سطح هدف و بازیابی تصویر از ImageReaderOutputConfigImpl استفاده می‌شود.

  3. onCaptureSessionStart و RequestProcessorImpl

    وقتی CameraCaptureSession شروع می‌شود و چارچوب «دوربین» onConfigured() را فرامی‌خواند، سپس Camera2/X SessionProcessorImpl.onCaptureSessionStart() را با پوشاننده درخواست Camera2 RequestProcessImpl فرامی‌خواند. ‫Camera2/X‏ RequestProcessImpl را پیاده‌سازی می‌کند، که به شما امکان می‌دهد درخواست‌های ضبط را اجرا کنید، و اگر از ImageReaderOutputConfigImpl استفاده شود، تصاویر را بازیابی کنید.

    میاناهای برنامه‌سازی کاربردی RequestProcessImpl ازنظر اجرای درخواست‌ها شبیه میاناهای برنامه‌سازی کاربردی Camera2 CameraCaptureSession هستند. تفاوت‌ها عبارت‌اند از:

    • سطح هدف با شناسه نمونه Camera2OutputConfigImpl مشخص می‌شود.
    • قابلیت بازیابی تصویر ImageReader.

    برای ثبت نمونه ImageProcessorImpl برای دریافت تصاویر، می‌توانید با RequestProcessorImpl.setImageProcessor() با شناسه Camera2OutputConfigImpl مشخص‌شده تماس بگیرید.

    نمونه RequestProcessImpl پس‌از فراخوانی Camera2/X SessionProcessorImpl.onCaptureSessionEnd() نامعتبر می‌شود.

  4. پیش‌نمایش را شروع کنید و عکس بگیرید

    در پیاده‌سازی «توسعه‌دهنده پیشرفته»، می‌توانید درخواست‌های ضبط را ازطریق رابط RequestProcessorImpl ارسال کنید. ‫Camera2/X با فراخوانی SessionProcessorImpl#startRepeating و SessionProcessorImpl#startCapture به شما اطلاع می‌دهد که درخواست تکرارشونده برای پیش‌نمایش یا توالی ضبط تصویر ثابت را شروع کنید. برای برآورده کردن این درخواست‌های پیش‌نمایش و عکس ثابت، باید درخواست‌های ضبط ارسال کنید.

    ‫Camera2/X همچنین پارامترهای درخواست ضبط را ازطریق SessionProcessorImpl#setParameters تنظیم می‌کند. باید این پارامترهای درخواست را (اگر پارامترها پشتیبانی می‌شوند) هم در درخواست‌های تکرارشونده و هم در درخواست‌های تکی تنظیم کنید.

    باید حداقل از CaptureRequest.JPEG_ORIENTATION و CaptureRequest.JPEG_QUALITY پشتیبانی کنید. extensions-interface 1.3.0 از کلیدهای درخواست و نتیجه پشتیبانی می‌کند که با روش‌های زیر نمایش داده می‌شوند:

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

    وقتی توسعه‌دهندگان کلیدها را در فهرست getAvailableCaptureRequestKeys تنظیم می‌کنند، باید پارامترها را فعال کنید و مطمئن شوید نتیجه ضبط حاوی کلیدهای فهرست getAvailableCaptureResultKeys باشد.

  5. startTrigger

    SessionProcessorImpl.startTrigger() برای شروع کردن راه‌انداز فراخوانده می‌شود، مثل CaptureRequest.CONTROL_AF_TRIGGER و CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER. می‌توانید کلیدهای درخواست ضبطی را که در AdvancedExtenderImpl.getAvailableCaptureRequestKeys() تبلیغ نشده‌اند نادیده بگیرید.

    ‫startTrigger() از extensions-interface نسخه ۱.۳.۰ پشتیبانی می‌شود. این برنامه به برنامه‌ها امکان می‌دهد تا با افزونه‌ها، تک‌ضرب زدن برای فوکوس و فلاش را پیاده‌سازی کنند.

  6. پاک‌سازی کردن

    هنگام پایان دادن به جلسه ضبط، SessionProcessorImpl.onCaptureSessionEnd() پیش‌از بستن CameraCaptureSession فراخوانده می‌شود. پس‌از بسته شدن جلسه ضبط، deInitSession() پاک‌سازی را انجام می‌دهد.

از پیش‌نمایش، ضبط تصویر ثابت، و تجزیه‌وتحلیل تصویر پشتیبانی می‌کند

باید افزونه را برای هر دو مورد استفاده پیش‌نمایش و ضبط تصویر ثابت اعمال کنید. بااین‌حال، اگر تأخیر خیلی زیاد باشد و پیش‌نمایش به‌نرمی نمایش داده نشود، می‌توانید افزونه را فقط برای ضبط تصویر ثابت اعمال کنید.

برای نوع «توسعه‌دهنده پایه»، صرف‌نظر از فعال کردن افزونه برای پیش‌نمایش، باید هم ImageCaptureExtenderImpl و هم PreviewExtenderImpl را برای افزونه‌ای معین پیاده‌سازی کنید. اغلب، یک برنامه همچنین از یک جریان YUV برای تجزیه‌وتحلیل محتوای تصویر مانند یافتن کدهای QR یا متن استفاده می‌کند. برای پشتیبانی بهتر از این مورد استفاده، باید از ترکیب جاری‌سازی پیش‌نمایش، ضبط تصویر ثابت، و جاری‌سازی YUV_420_888 برای پیکربندی CameraCaptureSession پشتیبانی کنید. این یعنی اگر پردازنده‌ای پیاده‌سازی کنید، باید از ترکیب جاری‌سازی سه YUV_420_888 جاری‌سازی پشتیبانی کنید.

برای «توسعه‌دهنده پیشرفته»، Camera2/X سه سطح برونداد را به SessionProcessorImpl.initSession() تماس منتقل می‌کند. این سطوح برونداد به‌ترتیب برای پیش‌نمایش، ضبط تصویر ثابت، و تحلیل تصویر است. باید مطمئن شوید که سطوح برونداد پیش‌نمایش و ضبط تصویر ثابت برونداد معتبر را نشان دهند. بااین‌حال، برای سطح خروجی تحلیل تصویر، مطمئن شوید که فقط زمانی کار می‌کند که غیرتهی باشد. اگر پیاده‌سازی شما نمی‌تواند از جاری‌سازی تجزیه‌وتحلیل تصویر پشتیبانی کند، می‌توانید فهرست خالی‌ای در AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() برگردانید. این کار تضمین می‌کند که سطح برونداد تجزیه‌وتحلیل تصویر در SessionProcessorImpl.initSession() همیشه تهی باشد.

پشتیبانی از ضبط ویدیو

معماری «افزونه دوربین» فعلی فقط از موارد استفاده پیش‌نمایش و عکس ثابت پشتیبانی می‌کند. ما از فعال کردن افزونه در سطوح MediaCodec یا MediaRecorder برای ضبط ویدیو پشتیبانی نمی‌کنیم. بااین‌حال، برنامه‌ها می‌توانند برونداد پیش‌نمایش را ضبط کنند.

پشتیبانی از سطوح MediaCodec و MediaRecorder دردست بررسی است.

فراداده‌های مختص افزونه

در Android 14 و بالاتر، فراداده مختص افزونه به مشتریان افزونه دوربین امکان می‌دهد تنظیمات و نتایج درخواست ضبط مختص افزونه را تنظیم و دریافت کنند. به‌طور خاص، کلاینت‌های افزونه دوربین می‌توانند از پارامتر درخواست ضبط EXTENSION_STRENGTH برای کنترل قدرت افزونه و از نتیجه ضبط EXTENSION_CURRENT_TYPE برای نشان دادن نوع افزونه فعال‌شده استفاده کنند.

درخواست‌های ضبط

پارامتر درخواست ضبط EXTENSION_STRENGTH قدرت جلوه پس‌پردازش افزونه را کنترل می‌کند. اگر این پارامتر به‌طور صریح توسط کارخواه تنظیم نشده باشد، نتیجه ضبط مربوطه شامل مقدار قدرت پیش‌فرض است. این پارامتر می‌تواند به‌صورت زیر برای این انواع افزونه اعمال شود:

  • ‫BOKEH: میزان محو کردن را کنترل می‌کند.
  • HDR و NIGHT: مقدار تصاویر ترکیب‌شده و روشنایی تصویر نهایی را کنترل می‌کند.
  • FACE_RETOUCH: میزان بهبود آرایشی و صاف کردن پوست را کنترل می‌کند.

محدوده پشتیبانی‌شده برای پارامتر EXTENSION_STRENGTH بین 0 و 100 است، به‌طوری‌که 0 نشان‌دهنده عدم پردازش افزونه یا عبور ساده و 100 نشان‌دهنده حداکثر قدرت افزونه اثر پردازش است.

برای افزودن پشتیبانی از EXTENSION_STRENGTH، از میاناهای برنامه‌سازی کاربردی پارامتر مختص فروشنده که در نسخه ۱.۳.۰ رابط کتابخانه افزونه معرفی شده است استفاده کنید. برای اطلاعات بیشتر، به getAvailableCaptureRequestKeys() مراجعه کنید.

نتایج ضبط

نتیجه EXTENSION_CURRENT_TYPE ضبط به پیاده‌سازی‌های افزونه امکان می‌دهد تا مشتریان را درباره نوع افزونه فعال مطلع کنند.

ازآنجایی‌که افزونه‌های استفاده‌کننده از نوع AUTO به‌طور پویا بین انواع افزونه مثل HDR و NIGHT بسته به شرایط صحنه جابه‌جا می‌شوند، برنامه‌های افزونه دوربین می‌توانند از EXTENSION_CURRENT_TYPE برای نمایش اطلاعات درباره افزونه انتخابی فعلی توسط افزونه AUTO استفاده کنند.

تخمین تأخیر در ضبط تصویر ثابت هم‌زمان

در Android 14 و نسخه‌های بالاتر، مشتریان افزونه دوربین می‌توانند بااستفاده از getRealtimeStillCaptureLatency()، تأخیر تخمینی ضبط تصویر ثابت هم‌زمان را براساس صحنه و شرایط محیطی پُرسمان کنند. این روش برآوردهای دقیق‌تری نسبت‌به روش getEstimatedCaptureLatencyRangeMillis() ایستا ارائه می‌دهد. برنامه‌ها براساس تخمین تأخیر می‌توانند تصمیم بگیرند که از پردازش افزونه صرف‌نظر کنند یا نشانگری نمایش دهند تا کاربران را از عملیات طولانی‌مدت مطلع کنند.

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();

برای پشتیبانی از تخمین‌های تأخیر ضبط تصویر ثابت هم‌زمان، موارد زیر را پیاده‌سازی کنید:

بازخوان‌های پیشرفت پردازش ضبط

برای Android 14 و بالاتر، کارخواه‌های افزونه دوربین می‌توانند برای پیشرفت عملیات پردازش عکس‌برداری طولانی‌مدت فراخوانی برگشتی دریافت کنند. برنامه‌ها می‌توانند پیشرفت فعلی را به کاربران نشان دهند تا تجربه کاربری کلی را بهبود بخشند.

برنامه‌ها می‌توانند از کد زیر برای ادغام این ویژگی استفاده کنند:

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
    }
  }
…
}

برای پشتیبانی از برگشت‌های پیشرفت پردازش ضبط، پیاده‌سازی فروشنده افزونه شما باید برگشت‌های زیر را با مقدار پیشرفت فعلی فراخوانی کند:

ضبط ثابت پس‌نما

برای Android 14 و نسخه‌های بالاتر، افزونه‌های دوربین می‌توانند بااستفاده از setPostviewOutputConfiguration یک پس‌نما (تصویر پیش‌نمایش) ارائه دهند. برای بهبود تجربه کاربر، برنامه‌ها می‌توانند وقتی افزونه‌ای با تأخیر پردازش افزایش‌یافته مواجه می‌شود، تصویر پس‌از مشاهده را به‌عنوان جای‌بان نمایش دهند و وقتی تصویر نهایی دردسترس قرار گرفت، آن را جایگزین کنند. برنامه‌ها می‌توانند درخواست‌های ضبط پس‌از مشاهده را بااستفاده از کد مرجع زیر پیکربندی و صادر کنند:

{
…
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();
…
}

برای پشتیبانی از ضبط عکس ثابت پس‌از مشاهده، پیاده‌سازی فروشنده شما باید موارد زیر را پیاده‌سازی کند:

پشتیبانی از برونداد SurfaceView

در Android 14 و نسخه‌های بالاتر، مشتریان افزونه دوربین می‌توانند با ثبت نمونه‌ای برای برونداد پیش‌نمایش برای درخواست‌های تکراری، از مسیرهای پردازشی پیش‌نمایش بهینه‌شده برای عملکرد و توان استفاده کنند. SurfaceView

برای پشتیبانی از برونداد SurfaceView، پیاده‌سازی افزونه فروشنده شما باید بتواند پیش‌نمایش را در SurfaceView نمونه جاری‌سازی و برونداد کند. برای تأیید اینکه این مورد پشتیبانی می‌شود، پودمان SurfaceViewExtensionPreviewTest.java CTS را اجرا کنید.

انواع جلسه خاص فروشنده

این ویژگی پیاده‌سازی‌های افزونه فروشنده را قادر می‌سازد نوع جلسه خاص فروشنده‌ای را انتخاب کند که به‌جای مقدار پیش‌فرض در جلسه ضبط دوربین داخلی تنظیم خواهد شد.

این ویژگی کاملاً در چارچوب و پشته فروشنده کار می‌کند و هیچ تأثیری بر API قابل‌مشاهده برای مشتری/عموم ندارد.

برای انتخاب نوع جلسه خاص فروشنده، موارد زیر را برای کتابخانه‌های افزونه‌تان پیاده‌سازی کنید: * ExtenderStateListener.onSessionType() برای افزونه‌های پایه * Camera2SessionConfigImpl.getSessionType() برای افزونه‌های پیشرفته

سابقه نسخه میانای افزونه‌ها

جدول زیر سابقه نسخه میانای «افزونه دوربین» را نشان می‌دهد. همیشه باید کتابخانه فروشنده را با جدیدترین نسخه پیاده‌سازی کنید.

نسخه ویژگی‌های اضافه‌شده
۱.۰.۰
  • درستی‌سنجی نسخه
    • ExtensionVersionImpl
  • توسعه‌دهنده پایه
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0
  • مقداردهی اولیه کتابخانه
    • InitializerImpl
  • نمایش وضوح‌های پشتیبانی‌شده
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
‫۱.۲.۰
  • AdvancedExtender
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • دریافت تأخیر تخمینی ضبط
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
‫۱.۳.۰
  • نمایش کلیدهای درخواست ضبط/کلیدهای نتایج پشتیبانی‌شده
    • ‫ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys و getAvailableCaptureResultKeys
    • ‫AdvancedExtenderImpl.getAvailableCaptureRequestKeys و getAvailableCaptureResultKeys
    • تماس process() جدید که ProcessResultImpl در PreviewImageProcessorImpl و CaptureProcessorImpl طول می‌کشد
    • درخواست نوع راه‌انداز پشتیبانی
      • AdvancedExtenderImpl.startTrigger
۱.۴.۰
  • فراداده‌های مختص افزونه
  • تخمین‌های تأخیر در ضبط تصویر ثابت پویا
  • بازخوان‌های پیشرفت پردازش ضبط
  • ضبط ثابت پس‌نما
  • پشتیبانی از خروجی SurfaceView
  • انواع جلسه خاص فروشنده

پیاده‌سازی مرجع

پیاده‌سازی‌های کتابخانه فروشنده سازنده اصلی محصول مرجع زیر در frameworks/ex دردسترس است.

  • ‫advancedSample: پیاده‌سازی پایه «توسعه‌دهنده پیشرفته».

  • ‫sample: پیاده‌سازی پایه «توسعه‌دهنده پایه».

  • service_based_sample: پیاده‌سازی‌ای که نحوه میزبانی «افزونه‌های دوربین» را در Service نشان می‌دهد. این پیاده‌سازی شامل عناصر زیر است:

    • oem_library: کتابخانه «سازنده اصلی محصول» «افزونه‌های دوربین» برای Camera2 و CameraX Extensions APIs که Extensions-Interface را پیاده‌سازی می‌کند. این ویژگی به‌عنوان یک گذرگاه عمل می‌کند که تماس‌ها را از Extensions-Interface به سرویس بازارسال می‌کند. این کتابخانه همچنین فایل‌های AIDL و کلاس‌های پوشاننده را برای برقراری ارتباط با سرویس ارائه می‌دهد.

      «توسعه‌دهنده پیشرفته» به‌طور پیش‌فرض فعال است. برای فعال کردن «توسعه‌دهنده پایه»، ExtensionsVersionImpl#isAdvancedExtenderImplemented را تغییر دهید تا false برگردد.

    • extensions_service: نمونه‌ای از پیاده‌سازی «سرویس افزونه‌ها». پیاده‌سازی خود را اینجا اضافه کنید. میانای پیاده‌سازی در سرویس مشابه Extensions-Interface است. برای مثال، پیاده‌سازی IAdvancedExtenderImpl.Stub همان عملیات AdvancedExtenderImpl را انجام می‌دهد. ‫ImageWrapper و TotalCaptureResultWrapper برای تبدیل Image و TotalCaptureResult به بسته‌شدنی لازم است.

راه‌اندازی کتابخانه فروشنده در دستگاه

کتابخانه فروشنده سازنده اصلی محصول در برنامه ساخته نشده است؛ این کتابخانه در زمان اجرا توسط Camera2/X از دستگاه بارگیری می‌شود. در CameraX، برچسب <uses-library> اعلام می‌کند که کتابخانه androidx.camera.extensions.impl، که در فایل AndroidManifest.xml کتابخانه camera-extensions تعریف شده است، وابستگی CameraX است و باید در زمان اجرا بار شود. در Camera2، چارچوب سرویس افزونه‌ای را بار می‌کند که همچنین اعلام می‌کند که <uses-library>کتابخانه androidx.camera.extensions.impl را در زمان اجرا بار می‌کند.

این کار به برنامه‌های طرف سوم که از افزونه‌ها استفاده می‌کنند امکان می‌دهد کتابخانه فروشنده OEM را به‌طور خودکار بار کنند. کتابخانه OEM به‌عنوان اختیاری علامت‌گذاری شده است تا برنامه‌ها بتوانند در دستگاه‌هایی که کتابخانه را در دستگاه ندارند اجرا شوند. وقتی برنامه‌ای سعی می‌کند از افزونه دوربین استفاده کند، Camera2/X این رفتار را به‌طور خودکار مدیریت می‌کند، به‌شرطی که سازنده دستگاه کتابخانه OEM را در دستگاه قرار دهد تا برنامه بتواند آن را پیدا کند.

برای راه‌اندازی کتابخانه سازنده اصلی محصول در دستگاه، مراحل زیر را انجام دهید:

  1. فایل اجازه‌ای را که برچسب <uses-library> به آن نیاز دارد بااستفاده از قالب زیر اضافه کنید: /etc/permissions/ANY_FILENAME.xml. برای مثال، /etc/permissions/camera_extensions.xml. فایل‌های موجود در این دایرکتوری، نگاشتی از کتابخانه نام‌گذاری‌شده در <uses-library> به مسیر واقعی فایل در دستگاه ارائه می‌دهند.
  2. از مثال زیر برای افزودن اطلاعات موردنیاز به فایل استفاده کنید.

    • ‫name باید androidx.camera.extensions.impl باشد زیرا CameraX در این کتابخانه جستجو می‌کند.
    • file مسیر مطلق فایلی است که حاوی پیاده‌سازی افزونه‌ها است (برای مثال، /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>

در Android 12 یا بالاتر، دستگاه‌هایی که از افزونه‌های CameraX پشتیبانی می‌کنند باید دارایی ro.camerax.extensions.enabled را روی true تنظیم کرده باشند، که امکان پُرسمان درباره پشتیبانی دستگاه از افزونه‌ها را فراهم می‌کند. برای انجام این کار، خط زیر را به فایل ساخت دستگاه اضافه کنید:

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

اعتبارسنجی

برای آزمایش پیاده‌سازی کتابخانه فروشنده سازنده تجهیزات اصلی در مرحله توسعه، از برنامه نمونه در androidx-main/camera/integration-tests/extensionstestapp/ استفاده کنید که ازطریق افزونه‌های فروشنده مختلف اجرا می‌شود.

پس‌از تکمیل پیاده‌سازی، از ابزار اعتبارسنجی افزونه‌های دوربین برای اجرای آزمایش‌های خودکار و دستی استفاده کنید تا تأیید کنید که کتابخانه فروشنده به‌درستی پیاده‌سازی شده است.

حالت صحنه گسترده دربرابر افزونه‌های دوربین

برای افزونه بوکه، علاوه‌بر نمایان کردن آن بااستفاده از افزونه‌های دوربین، می‌توانید افزونه را بااستفاده از حالت صحنه گسترده که ازطریق کلید CONTROL_EXTENDED_SCENE_MODE فعال می‌شود نمایان کنید. برای جزئیات بیشتر درباره پیاده‌سازی، به بوکه دوربین مراجعه کنید.

حالت صحنه گسترده در مقایسه با افزونه‌های دوربین برای برنامه‌های camera2 محدودیت‌های کمتری دارد. برای مثال، می‌توانید حالت صحنه گسترده را در نمونه معمولی CameraCaptureSession که از ترکیب‌های جاری انعطاف‌پذیر و پارامترهای درخواست ضبط پشتیبانی می‌کند فعال کنید. درمقابل، افزونه‌های دوربین فقط از مجموعه ثابتی از انواع جاری‌سازی پشتیبانی می‌کنند و پشتیبانی محدودی از پارامترهای درخواست ضبط دارند.

یکی از معایب حالت صحنه گسترده این است که فقط می‌توانید آن را در لایه انتزاعی سخت‌افزار دوربین پیاده‌سازی کنید، که یعنی باید تأیید شود که در همه کنترل‌های متعامد دردسترس توسعه‌دهندگان نرم‌افزار کار می‌کند.

توصیه می‌کنیم بااستفاده از هر دو حالت صحنه گسترده و «افزونه‌های دوربین»، بوکه را آشکار کنید زیرا برنامه‌ها ممکن است ترجیح دهند از یک API خاص برای فعال کردن بوکه استفاده کنند. توصیه می‌کنیم ابتدا از حالت صحنه گسترده استفاده کنید زیرا این روش انعطاف‌پذیرترین راه برای برنامه‌ها است تا افزونه بوکه را فعال کنند. سپس می‌توانید میانای افزونه‌های دوربین را براساس حالت صحنه گسترده پیاده‌سازی کنید. اگر پیاده‌سازی بوکه در HAL دوربین دشوار است، برای مثال، چون به پردازشگر پسینی نیاز دارد که در لایه برنامه برای پردازش تصاویر اجرا شود، توصیه می‌کنیم افزونه بوکه را بااستفاده از رابط «افزونه‌های دوربین» پیاده‌سازی کنید.

پرسشگان (FAQ)

آیا محدودیت‌هایی برای سطوح API وجود دارد؟

بله. این به مجموعه ویژگی‌های Android API که اجرای کتابخانه فروشنده OEM به آن نیاز دارد بستگی دارد. برای مثال، ExtenderStateListener.onPresetSession() از SessionConfiguration.setSessionParameters() تماس برای تنظیم مجموعه پایه برچسب‌ها استفاده می‌کند. این فراخوانی فقط در سطح API ۲۸ و بالاتر دردسترس است. برای جزئیات مربوط به روش‌های میانای خاص، به اسناد مرجع میانای برنامه‌سازی کاربردی مراجعه کنید.