יצרני מכשירים יכולים לחשוף תוספים כמו בוקה, מצב לילה ו-HDR למפתחים של צד שלישי דרך ממשק Camera Extensions שסופק על ידי ספריית ספקי ה-OEM. מפתחים יכולים להשתמש ב-Camera2 Extensions API וב-CameraX Extensions API כדי לגשת לתוספים שהוטמעו בספריית הספקים של יצרן ה-OEM.
רשימת התוספים הנתמכים, שהיא זהה ב-Camera2 וב-CameraX, מופיעה במאמר בנושא CameraX Extensions API. אם רוצים להוסיף תוסף, צריך לדווח על באג באמצעות כלי המעקב אחר בעיות.
בדף הזה מוסבר איך מטמיעים ומפעילים את ספריית ספקי ה-OEM במכשירים.
ארכיטקטורה
בתרשים הבא מתוארת הארכיטקטורה של ממשק Camera Extensions או extensions-interface
:
איור 1. תרשים ארכיטקטורה של תוספי מצלמה
כפי שמוצג בתרשים, כדי לתמוך בתוספי מצלמה, צריך להטמיע את extensions-interface
שסופק על ידי ספריית ספק ה-OEM. ספריית הספק של יצרן הציוד המקורי מאפשרת שני ממשקי API: CameraX Extensions API ו-Camera2 Extensions API, שמשמשים את אפליקציות CameraX ו-Camera2, בהתאמה, כדי לגשת לתוספים של הספק.
הטמעה של ספריית ספקים של OEM
כדי להטמיע את ספריית הספקים של יצרן ציוד מקורי, מעתיקים את הקבצים camera-extensions-stub
לפרויקט של ספריית מערכת. הקבצים האלה מגדירים את הממשק של Camera Extensions.
קובצי 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
מחלקות להרחבת Bokeh (צריך להטמיע אותן אם יש תמיכה בתוסף Bokeh)
BokehImageCaptureExtenderImpl.java
BokehPreviewExtenderImpl.java
advanced/BokehAdvancedExtenderImpl.java
כיתות להארכת הלילה (מטמיעים את התכונה אם היא נתמכת)
NightImageCaptureExtenderImpl.java
NightPreviewExtenderImpl.java
advanced/NightAdvancedExtenderImpl.java
מחלקות להרחבה אוטומטית (צריך להטמיע אותן אם יש תמיכה בהרחבה אוטומטית)
AutoImageCaptureExtenderImpl.java
AutoPreviewExtenderImpl.java
advanced/AutoAdvancedExtenderImpl.java
מחלקות של HDR extender (צריך להטמיע אותן אם יש תמיכה בהרחבת HDR)
HdrImageCaptureExtenderImpl.java
HdrPreviewExtenderImpl.java
advanced/HdrAdvancedExtenderImpl.java
מחלקות להרחבת התכונה 'ריטוש פנים' (צריך להטמיע אותן אם התוסף 'ריטוש פנים' נתמך)
BeautyImageCaptureExtenderImpl.java
BeautyPreviewExtenderImpl.java
advanced/BeautyAdvancedExtenderImpl.java
כלים (אופציונלי, אפשר למחוק)
advanced/Camera2OutputConfigImplBuilder.java
advanced/Camera2SessionConfigImplBuilder.java
לא חייבים לספק הטמעה לכל תוסף. אם לא מטמיעים תוסף, מגדירים את isExtensionAvailable()
להחזרת false
או מסירים את המחלקות המתאימות של Extender. ממשקי ה-API של Camera2 ו-CameraX Extensions מדווחים לאפליקציה שהתוסף לא זמין.
במאמר הזה נסביר איך ממשקי ה-API של Camera2 ו-CameraX Extensions פועלים עם ספריית הספק כדי להפעיל תוסף. התרשים הבא ממחיש את התהליך מקצה לקצה באמצעות התוסף Night כדוגמה:
איור 2. הטמעה של תוסף לילה
אימות הגרסה:
Camera2/X קוראת ל-
ExtensionVersionImpl.checkApiVersion()
כדי לוודא שהגרסהextensions-interface
שהוטמעה על ידי יצרן הציוד המקורי תואמת לגרסאות שנתמכות על ידי Camera2/X.הפעלה של ספריית הספקים:
InitializerImpl
כולל שיטהinit()
שמאתחלת את ספריית הספק. האתחול של Camera2/X מסתיים לפני הגישה למחלקות Extender.יצירת מופעים של מחלקות Extender:
יוצר מופע של מחלקות Extender עבור התוסף. יש שני סוגים של כלי להרחבת מילות מפתח: כלי בסיסי להרחבת מילות מפתח וכלי מתקדם להרחבת מילות מפתח. צריך להטמיע סוג Extender אחד לכל התוספים. מידע נוסף זמין במאמר בנושא ההבדלים בין כלי בסיסי להרחבת טווח החיפוש לבין כלי מתקדם להרחבת טווח החיפוש.
Camera2/X יוצר אינסטנסים של מחלקות Extender ומקיים איתן אינטראקציה כדי לאחזר מידע ולהפעיל את התוסף. עבור תוסף נתון, Camera2/X יכול ליצור מופעים של מחלקות Extender מספר פעמים. לכן, לא כדאי לבצע אתחול כבד בבונה או בקריאה
init()
. הפעולות הכבדות מתבצעות רק כשסשן המצלמה עומד להתחיל, למשל כשמתבצעת קריאה ל-onInit()
ב-Basic Extender או כשמתבצעת קריאה ל-initSession()
ב-Advanced Extender.בתוסף Night, מופעלות הדוגמאות הבאות של מחלקות Extender עבור סוג Basic Extender:
NightImageCaptureExtenderImpl.java
NightPreviewExtenderImpl.java
ובסוג Advanced Extender:
NightAdvancedExtenderImpl.java
בדיקת הזמינות של התוסף:
לפני שמפעילים את התוסף,
isExtensionAvailable()
בודק אם התוסף זמין במזהה המצלמה שצוין דרך מופע Extender.מאחלים את המאריך עם פרטי המצלמה:
Camera2/X מתקשרת אל
init()
במופע של Extender ומעבירה לו את מזהה המצלמה ואתCameraCharacteristics
.פרטי השאילתה:
מפעיל את המחלקה Extender כדי לאחזר מידע כמו רזולוציות נתמכות, עדיין ללכוד את השהייה המשוערת וללכוד מפתחות בקשה מה-Extender בהכנה להפעלת התוסף.
הפעלת התוסף ב-Extender:
המחלקה Extender מספקת את כל הממשקים שנדרשים להפעלת המחלקה. היא מציעה מנגנון לחיבור הטמעה של יצרן ציוד מקורי (OEM) לצינור העיבוד של Camera2, כמו הוספת פרמטרים של בקשת צילום או הפעלת מעבד פוסט.
בסוג Advanced Extender, Camera2/X מתקשר עם
SessionProcessorImpl
כדי להפעיל את התוסף. Camera2/X מאחזר את מופעSessionProcessorImpl
על ידי קריאה ל-createSessionProcessor()
ב-Extender.
בקטעים הבאים מוסבר בפירוט על תהליך ההרחבה.
אימות גרסה
כשספריית הספקים של יצרן ציוד מקורי (OEM) נטענת מהמכשיר בזמן ריצה, Camera2/X בודקת אם הספרייה תואמת לגרסה extensions-interface
.
ב-extensions-interface
נעשה שימוש בניהול גרסאות סמנטי, או בפורמט MAJOR.MINOR.PATCH, לדוגמה, 1.1.0 או 1.2.0. עם זאת, במהלך אימות הגרסה נעשה שימוש רק בגרסאות הראשיות והמשניות.
כדי לאמת את הגרסה, מתבצעת קריאה ל-Camera2/X
ExtensionVersionImpl.checkApiVersion()
עם הגרסה הנתמכת
extensions-interface
. לאחר מכן, המערכת Camera2/X משתמשת בגרסה שדווחה על ידי ספריית ה-OEM כדי לקבוע אם אפשר להפעיל את התוסף ואילו יכולות הוא צריך להפעיל.
תאימות לגרסה ראשית
אם הגרסאות העיקריות של ממשק התוסף שונות בין Camera2/X לבין ספריית הספק, התוסף נחשב לא תואם והוא מושבת.
תאימות לדורות קודמים
כל עוד הגרסה הראשית זהה, Camera2/X מבטיחה תאימות לאחור לספריות של ספקי OEM שנבנו עם גרסאות קודמות של extensions-interface
. לדוגמה, אם Camera2/X תומכת בגרסה 1.3.0, ספריות הספקים של יצרני הציוד המקורי שהטמיעו את גרסאות 1.0.0, 1.1.0 ו-1.2.0 עדיין תואמות.extensions-interface
זה גם אומר שאחרי שמטמיעים גרסה ספציפית של ספריית הספק, Camera2/X מוודא שהספרייה תואמת לאחור לגרסאות extension-interface
עתידיות.
תאימות קדימה
תאימות קדימה לספריות של ספקים בגרסאות חדשות יותר של extensions-interface
תלויה בכם, יצרני ה-OEM. אם אתם צריכים תכונות מסוימות כדי להטמיע את התוספים, כדאי להפעיל את התוספים החל מגרסה מסוימת. במקרה כזה, אפשר להחזיר את הגרסה הנתמכת של extensions-interface
אם גרסת הספרייה Camera2/X עומדת בדרישות. אם גרסאות Camera2/X לא נתמכות, אפשר להחזיר גרסה לא תואמת כמו 99.0.0 כדי להשבית את התוספים.
הפעלה ראשונית של ספריית ספק
אחרי אימות הגרסה extensions-interface
שהוטמעה בספריית ה-OEM, Camera2/X מתחיל את תהליך האתחול. השיטה InitializerImpl.init()
מאותתת לספריית ה-OEM שאפליקציה מנסה להשתמש בתוספים.
Camera2/X לא מבצעת קריאות נוספות לספריית ה-OEM (מלבד בדיקת הגרסה) עד שספריית הספק של ה-OEM קוראת ל-OnExtensionsInitializedCallback.onSuccess()
כדי להודיע על השלמת האתחול.
צריך להטמיע את
InitializerImpl
מגרסה extensions-interface
1.1.0. Camera2/X מדלג על שלב האתחול של הספרייה אם ספריית הספק של יצרן הציוד המקורי מטמיעה את extensions-interface
1.0.0.
השוואה בין כלי בסיסי להרחבת קהלים לבין כלי מתקדם להרחבת קהלים
יש שני סוגים של הטמעה של extensions-interface
: Basic Extender ו-Advanced Extender. התמיכה ב-Advanced Extender החלה בגרסה extensions-interface
1.2.0.
הטמעת Basic Extender לתוספים שמבצעים עיבוד של תמונות ב-HAL של המצלמה או שמשתמשים במעבד פוסט שיכול לעבד זרמי YUV.
הטמעה של Advanced Extender לתוספים שצריכים להתאים אישית את הגדרות הסטרימינג של Camera2 ולשלוח בקשות צילום לפי הצורך.
השוואה בין התכונות מופיעה בטבלה הבאה:
Basic Extender | הרחבה מתקדמת | |
---|---|---|
הגדרות של עדכונים לכיתה | קבוע תצוגה מקדימה: PRIVATE או YUV_420_888 (אם קיים מעבד) תמונה סטטית: JPEG או YUV_420_888 (אם קיים מעבד)
|
ניתן להתאמה אישית על ידי יצרן הציוד המקורי. |
שליחת בקשה לצילום מסך | רק Camera2/X יכולה לשלוח בקשות צילום. אפשר להגדיר את הפרמטרים לבקשות האלה. כשמעבד מסופק לצילום תמונות, Camera2/X יכול לשלוח כמה בקשות לצילום ולשלוח את כל התמונות ואת תוצאות הצילום למעבד. | מוקצה לכם מופע RequestProcessorImpl כדי להריץ את בקשת הצילום של camera2 ולקבל תוצאות ותמונה.
Camera2/X מפעיל את |
Hooks בצינור העברת הנתונים של המצלמה |
|
|
מתאים ל | תוספים שמוטמעים ב-HAL של המצלמה או במעבד שמבצע עיבוד של תמונות YUV. |
|
גרסת ה-API הנתמכת | Camera2 Extensions: Android 13 ואילך CameraX Extensions: camera-extensions 1.1.0 ואילך |
תוספים ל-Camera2: Android 12L ואילך תוספים ל-CameraX: camera-extensions 1.2.0-alpha03 ואילך |
מסלולי המשתמש באפליקציה
בטבלה הבאה מוצגים שלושה סוגים של תהליכי עבודה באפליקציה והקריאות המתאימות ל-Camera Extensions API. Camera2/X מספקת את ממשקי ה-API האלה, אבל צריך להטמיע את ספריית הספק בצורה נכונה כדי לתמוך בתהליכים האלה, שמתוארים בפירוט רב יותר בקטע בהמשך.
תוספים של Camera2 | תוספים ל-CameraX | |
---|---|---|
זמינות של תוספי שאילתות | CameraExtensionCharacteristics
.getSupportedExtensions
|
ExtensionsManager.
isExtensionAvailable
|
מידע על השאילתה | CameraExtensionCharacteristics.
getExtensionSupportedSizes
CameraExtensionCharacteristics.
getEstimatedCaptureLatencyRangeMillis
CameraExtensionCharacteristics.
getAvailableCaptureRequestKeys
CameraExtensionCharacteristics.
getAvailableCaptureResultKeys
|
ExtensionsManager.
getEstimatedCaptureLatencyRange
CameraX מטפלת בשאר המידע בספרייה. |
תצוגה מקדימה וצילום תמונות כשהתוסף מופעל | CameraDevice.
createExtensionSession
|
val cameraSelector = ExtensionsManager.
getExtensionEnabledCameraSelector
|
Basic Extender
ממשק Basic Extender מספק נקודות חיבור לכמה מקומות בצינור העיבוד של המצלמה. לכל סוג של תוסף יש מחלקות Extender תואמות שספקי OEM צריכים להטמיע.
בטבלה הבאה מפורטים סוגי ה-Extender שספקי OEM צריכים להטמיע עבור כל תוסף:
Extender classes to implement | |
---|---|
לילה | NightPreviewExtenderImpl.java
|
HDR | HdrPreviewExtenderImpl.java
|
אוטומטי | AutoPreviewExtenderImpl.java
|
Bokeh | BokehPreviewExtenderImpl.java
|
ריטוש פנים | BeautyPreviewExtenderImpl.java
|
בדוגמה הבאה אנחנו משתמשים ב-PreviewExtenderImpl
וב-ImageCaptureExtenderImpl
כערכי placeholder. מחליפים אותם בשמות של הקבצים שאתם מטמיעים.
ל-Basic Extender יש את היכולות הבאות:
- הוספת פרמטרים של סשן כשמגדירים את
CameraCaptureSession
(onPresetSession
). - הודעה על אירועי הפתיחה והסגירה של סשן הלכידה, ושליחת בקשה אחת להודעה ל-HAL עם הפרמטרים שמוחזרים (
onEnableSession
,onDisableSession
). - הוספת פרמטרים של תיעוד לבקשה
(
PreviewExtenderImpl.getCaptureStage
,ImageCaptureExtenderImpl.getCaptureStages
). - הוספת מעבדים לתצוגה מקדימה ולצילום תמונות סטילס שיכולים לעבד זרם
YUV_420_888
.
נראה איך Camera2/X מפעיל את extensions-interface
כדי להשיג את שלושת תהליכי העבודה של האפליקציה שצוינו למעלה.
תהליך באפליקציה 1: בדיקת הזמינות של התוסף
איור 3. תהליך באפליקציה 1 ב-Basic Extender
בתהליך הזה, Camera2/X קוראת ישירות לשיטה isExtensionAvailable()
של PreviewExtenderImpl
ושל ImageCaptureExtenderImpl
בלי לקרוא ל-init()
. כדי להפעיל את התוספים, שתי המחלקות של Extender צריכות להחזיר true
.
לרוב זה השלב הראשון באפליקציות כדי לבדוק אם סוג התוסף שצוין נתמך עבור מזהה מצלמה מסוים לפני שמפעילים את התוסף. הסיבה לכך היא שחלק מהתוספים נתמכים רק במזהי מצלמה מסוימים.
תהליך העבודה באפליקציה 2: שליחת שאילתה לקבלת מידע
איור 4. תהליך האפליקציה 2 ב-Basic Extender
אחרי שקובעים אם התוסף זמין, האפליקציות צריכות לשלוח שאילתה לגבי המידע הבא לפני שמפעילים את התוסף.
Still capture latency range:
ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
מחזירה את הטווח של השהיית הלכידה של האפליקציה כדי להעריך אם מתאים להפעיל את התוסף בתרחיש הנוכחי.גדלים נתמכים לתצוגה מקדימה ולמשטח ללכידת תמונות: הפונקציות
ImageCaptureExtenderImpl.getSupportedResolutions
ו-PreviewExtenderImpl.getSupportedResolutions
מחזירות רשימה של פורמטים של תמונות וגדלים שנתמכים עבור פורמט וגודל של משטח.מפתחות נתמכים של בקשות ותוצאות: Camera2/X מפעיל את השיטות הבאות כדי לאחזר את מפתחות הבקשות והתוצאות הנתמכים של לכידה מההטמעה שלכם:
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
ImageCaptureExtenderImpl.getAvailableCapturetResultKeys
Camera2/X תמיד קוראת ל-init()
קודם במחלקות Extender האלה לפני שהיא מבקשת מידע נוסף.
תהליך העבודה באפליקציה 3: תצוגה מקדימה/צילום תמונה כשהתוסף מופעל (הטמעה של HAL)
איור 5. תהליך האפליקציה 3 ב-Basic Extender
בתרשים שלמעלה מוצג התהליך העיקרי של הפעלת התצוגה המקדימה וצילום תמונות סטילס באמצעות תוסף ללא מעבד. כלומר, ה-HAL של המצלמה מעבד את התוסף.
בתהליך הזה, Camera2/X קודם קוראת ל-init()
ואז ל-onInit
, שמיידעת אתכם שסשן מצלמה עומד להתחיל עם התוספים שצוינו.
אפשר לבצע אתחול של פעולות כבדות ב-onInit()
.
כשמגדירים את CameraCaptureSession
, Camera2/X מפעיל את onPresetSession
כדי לקבל את פרמטרים של הסשן. אחרי שמגדירים את סשן הצילום בהצלחה, Camera2/X מפעיל את onEnableSession
ומחזיר מופע של CaptureStageImpl
שמכיל את פרמטרי הצילום. Camera2/X שולחת מיד בקשה אחת עם פרמטרים של לכידה כדי להודיע ל-HAL. באופן דומה, לפני שסוגרים את סשן הצילום, 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 משתמשת במשטחYUV_420_888
במקום ב-PRIVATE
כדי להגדיר אתCameraCaptureSession
לתצוגה מקדימה.התרשים הבא ממחיש את התהליך:
איור 6. תצוגה מקדימה של התהליך עם 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
.
אפשר להניח בבטחה שהתצוגה המקדימה מופעלת ופועלת לפני ששולחים את הבקשה לצילום תמונה.
בתרשים הבא אפשר לראות את התהליך:
איור 7. המשך תיעוד הזרימה באמצעות CaptureProcessorImpl
Camera2/X משתמשת במשטח בפורמט
YUV_420_888
לצילום תמונות כדי להגדיר את סשן הצילום. Camera2/X מכין אתCaptureProcessorImpl
על ידי קריאה ל:-
CaptureProcessorImpl.onImageFormatUpdate()
עםYUV_420_888
. -
CaptureProcessorImpl.onResolutionUpdate()
עם גודל תמונת הקלט. -
CaptureProcessorImpl.onOutputSurface()
עם פלטYUV_420_888
surface.
-
ImageCaptureExtenderImpl.getCaptureStages
מחזירה רשימה שלCaptureStageImpl
, כאשר כל רכיב ממופה למופעCaptureRequest
עם פרמטרים של לכידה שנשלחים על ידי Camera2/X. לדוגמה, אם הפונקציה מחזירה רשימה של שלושה מופעים שלCaptureStageImpl
, Camera2/X שולחת שלוש בקשות צילום עם פרמטרים מתאימים של צילום באמצעות ה-APIcaptureBurst
.התמונות והמופעים של
TotalCaptureResult
שמתקבלים נארזים יחד ונשלחים אלCaptureProcessorImpl
לעיבוד.
CaptureProcessorImpl
כותב את התוצאה Image (פורמטYUV_420_888
) אל משטח הפלט שצוין על ידי הקריאהonOutputSurface()
. המצלמה Camera2/X ממירה אותו לתמונות JPEG אם צריך.
תמיכה בתוצאות ובמפתחות של בקשות ללכידת נתונים
בנוסף לתצוגה מקדימה של המצלמה ולצילום, אפליקציות יכולות להגדיר זום, פרמטרים של פלאש או להפעיל הקשה כדי להתמקד. יכול להיות שהפרמטרים האלה לא תואמים להטמעה של התוסף.
הוספנו לגרסה extensions-interface
1.3.0 את השיטות הבאות כדי לאפשר לכם לחשוף את הפרמטרים שההטמעה שלכם תומכת בהם:
-
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys()
מחזירה את המפתחות של בקשות הצילום שנתמכים בהטמעה שלכם. -
ImageCaptureExtenderImpl.getAvailableCaptureResultKeys()
מחזירה את המפתחות של תוצאות הצילום שנכללים בתוצאות הצילום.
אם רכיב HAL של המצלמה מעבד את התוסף, Camera2/X מאחזר את תוצאות הצילום ב-CameraCaptureSession.CaptureCallback
. אבל אם המעבד מיושם, אז Camera2/X מאחזר את תוצאות הצילום ב-ProcessResultImpl
, שמועבר למתודה process()
ב-PreviewImageProcessorImpl
וב-CaptureProcessorImpl
.
אתם אחראים לדווח על תוצאת הצילום דרך ProcessResultImpl
אל Camera2/X.
לדוגמה, אפשר לעיין בהגדרה של הממשק CaptureProcessorImpl
שבהמשך.
ב-extensions-interface
1.3.0 ואילך, מתבצעת קריאה שנייה ל-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
במקרה של תוספים בסיסיים שמטמיעים גרסה 1.2.0 או גרסאות קודמות, CameraX Extensions API תומך באופן מפורש בכל המפתחות שלמעלה. בגרסה
extensions-interface
1.3.0, גם CameraX וגם Camera2 מכבדות את הרשימה שמוחזרת
ותומכות רק במפתחות שמופיעים בה. לדוגמה, אם מחליטים להחזיר רק את CaptureRequest#CONTROL_ZOOM_RATIO
ואת CaptureRequest#SCALER_CROP_REGION
בהטמעה של גרסה 1.3.0, המשמעות היא שרק זום נתמך באפליקציה, אבל לא ניתן להשתמש בהקשה למיקוד, בפלאש ובפיצוי חשיפה.
הרחבה מתקדמת
Advanced Extender הוא סוג של הטמעה של ספק שמבוססת על Camera2 API.
סוג ה-Extender הזה נוסף בגרסה extensions-interface
1.2.0. בהתאם ליצרן המכשיר, יכול להיות שהתוספים יוטמעו בשכבת האפליקציה, וזה תלוי בגורמים הבאים:
הגדרת סטרימינג בהתאמה אישית: הגדרה של סטרימינג בהתאמה אישית כמו סטרימינג RAW או הגדרה של כמה סטרימינג עם מזהי מצלמה פיזיים שונים.
יכולת לשלוח בקשות Camera2: תמיכה בלוגיקה מורכבת של אינטראקציה שיכולה לשלוח בקשות צילום עם פרמטרים שמבוססים על התוצאות של בקשות קודמות.
הכלי Advanced Extender מספק מעטפת או שכבת ביניים, כך שתוכלו להתאים אישית את הגדרות הסטרימינג ולשלוח בקשות ללכידת נתונים לפי דרישה.
קבצים להטמעה
כדי לעבור להטמעה של Advanced Extender, השיטה isAdvancedExtenderImplemented()
ב-ExtensionVersionImpl
צריכה להחזיר true
. יצרני ציוד מקורי (OEM) צריכים להטמיע את המחלקות המתאימות של Extender לכל סוג תוסף. קבצי ההטמעה של Advanced Extender נמצאים בחבילה advanced.
Extender classes to implement | |
---|---|
לילה | advanced/NightAdvancedExtenderImpl.java
|
HDR | advanced/HdrAdvancedExtenderImpl.java
|
אוטומטי | advanced/AutoAdvancedExtenderImpl.java
|
Bokeh | advanced/BokehAdvancedExtenderImpl.java
|
ריטוש פנים | advanced/BeautyAdvancedExtenderImpl.java
|
בדוגמה הבאה, אנחנו משתמשים ב-AdvancedExtenderImpl
כ-placeholder.
מחליפים אותו בשם של קובץ ה-Extender של התוסף שרוצים להטמיע.
בואו נראה איך Camera2/X מפעיל את extensions-interface
כדי להשיג את שלושת תהליכי העבודה באפליקציה.
תהליך באפליקציה 1: בדיקת הזמינות של תוספים
איור 8. תהליך באפליקציה 1 ב-Advanced Extender
קודם כול, האפליקציה בודקת אם יש תמיכה בסיומת שצוינה.
תהליך העבודה באפליקציה 2: שליחת שאילתה לקבלת מידע
איור 9. זרימת אפליקציה 2 ב-Advanced Extender
אחרי הקריאה ל-AdvancedExtenderImpl.init()
, האפליקציה יכולה לשלוח שאילתה לגבי המידע הבא ב-AdvancedExtenderImpl
:
השהיית צילום התמונות המשוערת: הפונקציה
AdvancedExtenderImpl.getEstimatedCaptureLatencyRange()
מחזירה את טווח ההשהיה של הצילום באפליקציה כדי לבדוק אם מתאים להפעיל את התוסף לתרחיש הנוכחי.רזולוציות נתמכות לתצוגה מקדימה ולצילום תמונות:
AdvancedExtenderImpl.getSupportedPreviewOutputResolutions()
מחזירה מיפוי של פורמט התמונה לרשימת הגדלים שנתמכים עבור פורמט וגודל של משטח תצוגה מקדימה. יצרני ציוד מקורי (OEM) צריכים לתמוך בפורמטPRIVATE
לפחות.
AdvancedExtenderImpl.getSupportedCaptureOutputResolutions()
מחזירה את הפורמט והגדלים הנתמכים של משטח ללכידת תמונות סטילס. יצרני ציוד מקורי חייבים לתמוך בפלט בפורמטיםJPEG
ו-YUV_420_888
.
AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
מחזירה את הגדלים הנתמכים של זרםYUV_420_888
נוסף לניתוח תמונות. אם אין תמיכה ב-YUV surface של ניתוח התמונות, הפונקציהgetSupportedYuvAnalysisResolutions()
צריכה להחזירnull
או רשימה ריקה.
מפתחות/תוצאות זמינים של בקשות צילום (נוספו בגרסה
extensions-interface
1.3.0): Camera2/X מפעילה את השיטות הבאות כדי לאחזר את מפתחות בקשות הצילום ומפתחות התוצאות הנתמכים מההטמעה שלכם:AdvancedExtenderImpl.getAvailableCaptureRequestKeys
AdvancedExtenderImpl.getAvailableCaptureResultKeys
מידע נוסף זמין במאמר בנושא תמיכה במפתחות ובתוצאות של בקשות ללכידת נתונים.
תהליך השימוש באפליקציה 3: תצוגה מקדימה או צילום תמונה כשהתוסף מופעל
איור 10. זרימת אפליקציה 3 ב-Advanced Extender
בתרשים שלמעלה מוצג התהליך העיקרי של הפעלת התצוגה המקדימה וצילום תמונות סטילס עבור סוג המאריך המתקדם. נסביר מה צריך לעשות בכל שלב.
SessionProcessorImpl
instanceההטמעה העיקרית של הכלי המתקדם להרחבת ההמרות נמצאת בקובץ
SessionProcessorImpl
, שאחראי על אספקת הגדרות מותאמות אישית של סשנים ועל שליחת בקשות לתיעוד כדי להתחיל את התצוגה המקדימה ולתעד את הבקשה. הפונקציהAdvancedExtenderImpl.createSessionProcessor()
מופעלת כדי להחזיר את המופעSessionProcessorImpl
.initSession
SessionProcessorImpl.initSession()
מאתחל את הסשן של התוסף. כאן מקצים משאבים ומחזירים הגדרת סשן להכנתCameraCaptureSession
.בפרמטרים של הקלט, Camera2/X מציין את ההגדרות של משטח הפלט לתצוגה מקדימה, לצילום תמונות סטילס ולניתוח אופציונלי של תמונת YUV. ההגדרה של משטח הפלט (
OutputSurfaceImpl
) מכילה את המשטח, הגודל ופורמט התמונה שאוחזרו באמצעות השיטות הבאות ב-AdvancedExtenderImpl
:getSupportedPreviewOutputResolutions()
getSupportedCaptureOutputResolutions()
getSupportedYuvAnalysisResolutions()
צריך להחזיר מופע של
Camera2SessionConfigImpl
, שמורכב מרשימה של מופעים שלCamera2OutputConfigImpl
ומהפרמטרים של הסשן שמשמשים להגדרתCameraCaptureSession
. אתם אחראים להפקת תמונות המצלמה הנכונות למשטחי הפלט שמועברים על ידי Camera2/X. אלה כמה אפשרויות להפעלת הפלט:- עיבוד ב-HAL של המצלמה: אפשר להוסיף ישירות את משטחי הפלט
ל-
CameraCaptureSession
באמצעות הטמעה שלSurfaceOutputConfigImpl
. ההגדרה הזו קובעת את משטח הפלט שסופק לצינור המצלמה ומאפשרת ל-HAL של המצלמה לעבד את התמונה. עיבוד של פלטפורמת
ImageReader
ביניים (RAW, YUV וכו'): מוסיפים את פלטפורמותImageReader
הביניים אלCameraCaptureSession
עם מופע שלImageReaderOutputConfigImpl
.צריך לעבד את תמונות הביניים ולכתוב את תמונת התוצאה אל משטח הפלט.
- שימוש בשיתוף משטחים של Camera2: כדי להשתמש בשיתוף משטחים עם משטח אחר, מוסיפים מופע
Camera2OutputConfigImpl
כלשהו לשיטהgetSurfaceSharingOutputConfigs()
של מופעCamera2OutputConfigImpl
אחר. הפורמט והגודל של פני השטח חייבים להיות זהים.
לכל
Camera2OutputConfigImpl
, כוללSurfaceOutputConfigImpl
ו-ImageReaderOutputConfigImpl
, צריך להיות מזהה ייחודי (getId()
), שמשמש לציון פלטפורמת היעד ולאחזור התמונה מ-ImageReaderOutputConfigImpl
.
onCaptureSessionStart
ו-RequestProcessorImpl
כש-
CameraCaptureSession
מתחיל וה-framework של המצלמה מפעיל אתonConfigured()
, Camera2/X מפעיל אתSessionProcessorImpl.onCaptureSessionStart()
עם העטיפהRequestProcessImpl
של בקשת Camera2. Camera2/X מטמיע אתRequestProcessImpl
, שמאפשר לכם להריץ את בקשות הצילום ולאחזר תמונות אם נעשה שימוש ב-ImageReaderOutputConfigImpl
.ממשקי ה-API של
RequestProcessImpl
דומים לממשקי ה-API של Camera2CameraCaptureSession
מבחינת ביצוע בקשות. ההבדלים הם:- משטח היעד מצוין על ידי המזהה של מופע
Camera2OutputConfigImpl
. - היכולת לאחזר את התמונה של
ImageReader
.
אפשר להתקשר למספר
RequestProcessorImpl.setImageProcessor()
עם מזההCamera2OutputConfigImpl
ספציפי כדי לרשום מופעImageProcessorImpl
לקבלת תמונות.המופע
RequestProcessImpl
הופך ללא חוקי אחרי קריאות של Camera2/XSessionProcessorImpl.onCaptureSessionEnd()
.- משטח היעד מצוין על ידי המזהה של מופע
הפעלת התצוגה המקדימה וצילום תמונה
בהטמעה של הכלי המתקדם להרחבת הכיסוי, אפשר לשלוח בקשות לכיסוי דרך הממשק של
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
.startTrigger
הפונקציה
SessionProcessorImpl.startTrigger()
מופעלת כדי להתחיל את הטריגר, כמוCaptureRequest.CONTROL_AF_TRIGGER
ו-CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER
. אפשר להתעלם ממפתחות של בקשות ללכידת נתונים שלא פורסמו ב-AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
.התמיכה ב-
startTrigger()
קיימת מאז גרסהextensions-interface
1.3.0. היא מאפשרת לאפליקציות להטמיע הקשה להתמקדות והבזק עם תוספים.פינוי נפח
בסיום סשן צילום, הפונקציה
SessionProcessorImpl.onCaptureSessionEnd()
מופעלת לפני הסגירה שלCameraCaptureSession
. אחרי שסוגרים את סשן הלכידה,deInitSession()
מבצע ניקוי.
תצוגה מקדימה של תמיכה, צילום תמונות וניתוח תמונות
כדאי להשתמש בתוסף גם בתרחישים לדוגמה של תצוגה מקדימה וגם בתרחישים לדוגמה של צילום תמונות. עם זאת, אם זמן האחזור גבוה מדי ואי אפשר להציג את התצוגה המקדימה בצורה חלקה, אפשר להחיל את התוסף רק על צילום תמונות סטילס.
בסוג Basic Extender, בלי קשר להפעלת התוסף לתצוגה מקדימה,
צריך להטמיע את ImageCaptureExtenderImpl
ואת PreviewExtenderImpl
עבור תוסף נתון. לעתים קרובות, אפליקציה משתמשת גם בזרם YUV כדי לנתח את תוכן התמונה, למשל כדי למצוא קודי QR או טקסט. כדי לתמוך בתרחיש השימוש הזה בצורה טובה יותר
, צריך לתמוך בשילוב של זרם תצוגה מקדימה, זרם של תמונות סטילס וזרם של YUV_420_888
כדי להגדיר את CameraCaptureSession
. המשמעות היא שאם מטמיעים מעבד, צריך לתמוך בשילוב של שלושה שידורים של YUV_420_888
.
ב-Advanced Extender, Camera2/X מעבירה שלוש משטחי פלט לשיחה SessionProcessorImpl.initSession()
. משטחי הפלט האלה מיועדים לתצוגה מקדימה, לצילום תמונות ולניתוח תמונות, בהתאמה. צריך לוודא שמשטחי הפלט של התצוגה המקדימה ושל צילום התמונות מציגים את הפלט התקין. עם זאת, לגבי משטח הפלט של ניתוח התמונה, צריך לוודא שהוא פועל רק כשהוא לא null. אם ההטמעה לא תומכת בזרם של ניתוח התמונות, אפשר להחזיר רשימה ריקה ב-AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
. כך מוודאים שפלט ניתוח התמונה תמיד יהיה null ב-SessionProcessorImpl.initSession()
.
תמיכה בצילום וידאו
הארכיטקטורה הנוכחית של Camera Extension תומכת רק בתרחישי השימוש של תצוגה מקדימה וצילום תמונות סטילס. אנחנו לא תומכים בהפעלת התוסף בפלטפורמות 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
, צריך להשתמש בממשקי ה-API של הפרמטרים הספציפיים לספק שהוצגו בגרסה 1.3.0 של ממשק ספריית התוספים. מידע נוסף זמין במאמר 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();
כדי לתמוך בהערכות של זמן האחזור של צילום תמונות סטילס בזמן אמת, צריך להטמיע את הפעולות הבאות:
- תוספים בסיסיים:
ImageCaptureExtenderImpl.getRealtimeCaptureLatency()
- תוספים מתקדמים:
SessionProcessorImpl.getRealtimeCaptureLatency
קריאות חוזרות (callback) לדיווח על התקדמות העיבוד
ב-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
}
}
…
}
כדי לתמוך בהחזרות (callback) של התקדמות העיבוד של הלכידה, ההטמעה של ספק התוסף צריכה לקרוא להחזרות הבאות עם ערך ההתקדמות הנוכחי:
- תוספים בסיסיים:
ProcessResultImpl.onCaptureProcessProgressed()
- תוספים מתקדמים:
CaptureCallback.onCaptureProcessProgressed()
צילום מסך של פוסט
ב-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();
…
}
כדי לתמוך בתיעוד של צילומי מסך אחרי צפייה, ההטמעה של הספק צריכה לכלול את הפעולות הבאות:
תוספים בסיסיים:
CaptureProcessorImpl.onPostviewOutputSurface
ו-CaptureProcessorImpl.processWithPostview
תוספים מתקדמים:
SessionProcessorImpl.startCaptureWithPostview
תמיכה בפלט של SurfaceView
ב-Android מגרסה 14 ואילך, לקוחות של תוספי מצלמה יכולים להשתמש בנתיבי עיבוד של תצוגה מקדימה שעברו אופטימיזציה לצריכת חשמל ולביצועים, על ידי רישום של מופע SurfaceView
לפלט של תצוגה מקדימה עבור בקשות חוזרות.
כדי לתמוך בפלט SurfaceView
, ההטמעה של תוסף הספק צריכה להיות מסוגלת להזרים ולהציג תצוגה מקדימה של פלט למופעים של SurfaceView
. כדי לוודא שיש תמיכה, מריצים את מודול SurfaceViewExtensionPreviewTest.java
CTS.
סוגי סשנים ספציפיים לספק
התכונה מאפשרת להטמעות של תוספים של ספקים לבחור סוג ספציפי של סשן של ספק שיוגדר בסשן הפנימי של צילום המצלמה במקום ערך ברירת המחדל.
התכונה פועלת באופן מלא במסגרת ובמערך הספקים, ואין לה השפעה על ה-API שגלוי ללקוחות או לציבור.
כדי לבחור סוג סשן ספציפי לספק, צריך להטמיע את הערכים הבאים בספריות התוספים:
* ExtenderStateListener.onSessionType()
לתוספים בסיסיים
* Camera2SessionConfigImpl.getSessionType()
לתוספים מתקדמים
היסטוריית הגרסאות של ממשק התוספים
בטבלה הבאה מפורטת היסטוריית הגרסאות של ממשק תוסף המצלמה. תמיד מומלץ להטמיע את ספריית הספק עם הגרסה העדכנית ביותר.
גרסה | תכונות שנוספו |
---|---|
1.0.0 |
|
1.1.0 |
|
1.2.0 |
|
1.3.0 |
|
1.4.0 |
|
הטמעה לדוגמה
ההטמעות הבאות של ספריות ספקים של יצרני ציוד מקורי זמינות ב-frameworks/ex
.
advancedSample
: הטמעה בסיסית של Advanced Extender.
sample
: הטמעה בסיסית של Basic Extender.
service_based_sample
: הטמעה שמדגימה איך לארח תוספי מצלמה ב-Service
. ההטמעה הזו כוללת את הרכיבים הבאים:
oem_library
: ספריית OEM של תוספי מצלמה ל-Camera2 ול-CameraX Extensions APIs שמטמיעה אתExtensions-Interface
. הוא פועל כצינור להעברת נתונים ומעביר שיחות מ-Extensions-Interface
לשירות. הספרייה הזו מספקת גם קובצי AIDL ומחלקות wrapper כדי לתקשר עם השירות.התכונה 'הארכת שיחות מתקדמת' מופעלת כברירת מחדל. כדי להפעיל את Basic Extender, צריך לשנות את
ExtensionsVersionImpl#isAdvancedExtenderImplemented
ל-returnfalse
.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>
loads the same
androidx.camera.extensions.impl
נטענת בזמן ריצה.
כך אפליקציות צד שלישי שמשתמשות בתוספים יכולות לטעון באופן אוטומטי את ספריית הספקים של יצרן הציוד המקורי (OEM). ספריית ה-OEM מסומנת כאופציונלית, כדי שאפליקציות יוכלו לפעול במכשירים שאין בהם את הספרייה. Camera2/X מטפל בהתנהגות הזו באופן אוטומטי כשמנסים להשתמש בהרחבה של מצלמה באפליקציה, כל עוד יצרן המכשיר מציב את ספריית ה-OEM במכשיר כך שהאפליקציה תוכל לגלות אותה.
כדי להגדיר את ספריית ה-OEM במכשיר:
- מוסיפים קובץ הרשאות, שנדרש על ידי התג
<uses-library>
, באמצעות הפורמט הבא:/etc/permissions/ANY_FILENAME.xml
. לדוגמה,/etc/permissions/camera_extensions.xml
. הקבצים בספרייה הזו מספקים מיפוי של הספרייה שצוינה ב-<uses-library>
לנתיב הקובץ בפועל במכשיר. בדוגמה שלמטה מוסבר איך להוסיף את המידע הנדרש לקובץ.
- הערך של
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
, כדי לאפשר שאילתה לגבי התמיכה של המכשיר בתוספים.
כדי לעשות את זה, מוסיפים את השורה הבאה לקובץ ה-make של המכשיר:
PRODUCT_VENDOR_PROPERTIES += \
ro.camerax.extensions.enabled=true \
אימות
כדי לבדוק את ההטמעה של ספריית ספקי ה-OEM במהלך שלב הפיתוח, אפשר להשתמש באפליקציה לדוגמה בכתובת androidx-main/camera/integration-tests/extensionstestapp/
, שמפעילה תוספים שונים של ספקים.
אחרי שמסיימים את ההטמעה, משתמשים בכלי לאימות תוספים למצלמה כדי להריץ בדיקות אוטומטיות וידניות ולוודא שהספרייה של הספק הוטמעה בצורה נכונה.
מצב סצנה מורחב לעומת תוספים למצלמה
כדי להשתמש בתוסף הבוקה, בנוסף לחשיפה שלו באמצעות תוספי מצלמה, אפשר לחשוף את התוסף באמצעות מצב הסצנה המורחב, שמופעל באמצעות המקש CONTROL_EXTENDED_SCENE_MODE
.
פרטים נוספים על ההטמעה זמינים במאמר Camera bokeh.
למצב סצנה מורחב יש פחות הגבלות בהשוואה לתוספי מצלמה באפליקציות camera2. לדוגמה, אפשר להפעיל מצב סצנה מורחב במופע רגיל של CameraCaptureSession
שתומך בשילובים גמישים של סטרימינג ובפרמטרים של בקשות צילום. לעומת זאת, תוספים למצלמה תומכים רק בקבוצה קבועה של סוגי סטרימינג, והתמיכה שלהם בפרמטרים של בקשות צילום מוגבלת.
חיסרון של מצב סצנה מורחב הוא שאפשר להטמיע אותו רק ב-HAL של המצלמה, כלומר צריך לוודא שהוא פועל בכל אמצעי הבקרה האורתוגונליים שזמינים למפתחי אפליקציות.
מומלץ לחשוף את אפקט הבוקה באמצעות מצב הסצנה המורחב וגם באמצעות Camera Extensions, כי יכול להיות שאפליקציות יעדיפו להשתמש בממשק API מסוים כדי להפעיל את אפקט הבוקה. מומלץ להשתמש קודם במצב הסצנה המורחב, כי זו הדרך הכי גמישה לאפליקציות להפעיל את תוסף הבוקה. לאחר מכן תוכלו להטמיע את ממשק תוספי המצלמה על סמך מצב הצילום המורחב. אם קשה להטמיע את אפקט הבוקה ב-HAL של המצלמה, למשל כי נדרש מעבד פוסט שפועל בשכבת האפליקציה כדי לעבד תמונות, מומלץ להטמיע את תוסף הבוקה באמצעות הממשק Camera Extensions.
שאלות נפוצות
יש הגבלות על רמות API?
כן. הדבר תלוי בקבוצת התכונות של Android API שנדרשת להטמעה של ספריית הספקים של יצרן הציוד המקורי. לדוגמה, ExtenderStateListener.onPresetSession()
משתמש בקריאה SessionConfiguration.setSessionParameters()
כדי להגדיר קבוצת תגים בסיסית. הקריאה הזו זמינה רק ברמה 28 של API ומעלה. פרטים על שיטות ספציפיות של ממשק מופיעים במאמרי העזרה של ה-API.