יצרני מכשירים יכולים לחשוף תוספים כמו בוקה, מצב לילה ו-HDR למפתחים של צד שלישי דרך ממשק התוספים למצלמה שמסופק על ידי ספריית הספק של ה-OEM. מפתחים יכולים להשתמש ב-Camera2 Extensions API וב-CameraX Extensions API כדי לגשת לתוספים שמופעלים בספריית הספק של יצרן הציוד המקורי.
רשימת התוספים הנתמכים, זהה ב-Camera2 וב-CameraX, מופיעה במאמר CameraX Extensions API. אם רוצים להוסיף תוסף, צריך לדווח על באג בכלי למעקב אחר בעיות.
בדף הזה נסביר איך מטמיעים ומפעילים את ספריית הספק של OEM במכשירים.
ארכיטקטורה
בתרשים הבא מתוארת הארכיטקטורה של הממשק של התוספים למצלמה, או extensions-interface
:
איור 1. תרשים הארכיטקטורה של התוספים למצלמה
כפי שמוצג בתרשים, כדי לתמוך בתוספים למצלמה, צריך להטמיע את extensions-interface
שמסופק על ידי ספריית הספק של ה-OEM. ספריית הספק של ה-OEM מאפשרת להשתמש בשני ממשקי API: CameraX Extensions API ו-Camera2 Extensions API, שבהם משתמשות האפליקציות CameraX ו-Camera2, בהתאמה, כדי לגשת לתוספים של ספקים.
הטמעת ספריית הספק של OEM
כדי להטמיע את ספריית הספק של ה-OEM, מעתיקים את הקבצים 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
מחלקות של Bokeh extender (צריך להטמיע אותן אם יש תמיכה בתוסף Bokeh)
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. ממשקי ה-API של התוספים של Camera2 ו-CameraX מדווחים לאפליקציה שהתוסף לא זמין.
נראה איך ממשקי ה-API של התוספים של Camera2 ו-CameraX פועלים עם ספריית הספק כדי להפעיל תוסף. התרשים הבא מדגים את התהליך מקצה לקצה באמצעות התוסף Night בתור דוגמה:
איור 2. הטמעה של תוסף לילה
אימות הגרסה:
Camera2/X מבצעת קריאה ל-
ExtensionVersionImpl.checkApiVersion()
כדי לוודא שהגרסה שלextensions-interface
שהוטמעה על ידי יצרן הציוד המקורי תואמת לגרסאות הנתמכות של Camera2/X.הפעלת ספריית הספק:
ל-
InitializerImpl
יש שיטהinit()
שמפעילה את ספריית הספק. Camera2/X משלים את האינטוליזציה לפני שהוא ניגש לכיתות Extender.יצירת מופעים של כיתות Extender:
יצירת מופע של כיתות Extender עבור התוסף. יש שני סוגים של Extender: Basic Extender ו-Advanced Extender. צריך להטמיע סוג אחד של Extender לכל התוספים. מידע נוסף זמין במאמר מַרחיב בסיסי לעומת מַרחיב מתקדם.
Camera2/X יוצר מופע של כיתות Extender ומקיים איתן אינטראקציה כדי לאחזר מידע ולהפעיל את התוסף. להרחבה נתונה, Camera2/X יכול ליצור עותקים של הכיתות של Extender כמה פעמים. לכן, אל תבצעו את עבודת האיפוס הכבדה ב-constructor או בקריאה ל-
init()
. כדאי לבצע את הפעולות הכבדות רק כשסשן המצלמה עומד להתחיל, למשל כשמתבצעת קריאה ל-onInit()
ב-Basic Extender או כשמתבצעת קריאה ל-initSession()
ב-Advanced Extender.בתוסף Night, הכיתות הבאות של Extender נוצרות עבור הסוג Basic Extender:
NightImageCaptureExtenderImpl.java
NightPreviewExtenderImpl.java
ועבור סוג Extender מתקדם:
NightAdvancedExtenderImpl.java
בודקים את הזמינות של התוסף:
לפני הפעלת התוסף,
isExtensionAvailable()
בודק אם התוסף זמין במזהה המצלמה שצוין באמצעות מכונה של Extender.מפעילים את המפצל באמצעות פרטי המצלמה:
Camera2/X קורא ל-
init()
במכונה של Extender ומעביר לה את מזהה המצלמה ו-CameraCharacteristics
.פרטי השאילתה:
הפונקציה מפעילה את הכיתה Extender כדי לאחזר מידע כמו רזולוציות נתמכות, עדיין לתעד זמן אחזור משוער ולתעד מפתחות בקשה מה-Extender לקראת הפעלת התוסף.
מפעילים את התוסף במכשיר ההרחבה:
מחלקת Extender מספקת את כל הממשקים הנדרשים כדי להפעיל את המחלקה. הוא מציע מנגנון לחיבור הטמעת OEM לצינור עיבוד הנתונים של Camera2, למשל הזרקת פרמטרים של בקשת צילום או הפעלת מעבד פוסט.
בסוג 'מגדיל מתקדם', Camera2/X יוצר אינטראקציה עם
SessionProcessorImpl
כדי להפעיל את התוסף. Camera2/X מאחזרת את המכונהSessionProcessorImpl
באמצעות קריאה ל-createSessionProcessor()
במכשיר ההרחבה.
בקטעים הבאים מתוארת תהליך ההוספה של התוסף בפירוט רב יותר.
אימות הגרסה
כשספריית הספק של ה-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 כדי לקבוע אם ניתן להפעיל את התוסף ואילו יכולות הוא צריך להפעיל.
תאימות לגרסה הראשית
אם הגרסאות הראשיות של extension-interface שונות בין Camera2/X לבין ספריית הספק, המערכת תתייחס לכך כאל חוסר תאימות והתוסף יושבת.
תאימות לאחור
כל עוד הגרסה הראשית זהה, Camera2/X מבטיחה תאימות לאחור לספריות של ספקי OEM שנוצרו בגרסאות קודמות של extensions-interface
. לדוגמה, אם Camera2/X תומכת ב-extensions-interface
1.3.0, ספריות הספקים של יצרני ציוד מקורי שהטמיעו את הגרסאות 1.0.0, 1.1.0 ו-1.2.0 עדיין תואמות. המשמעות היא גם שאחרי שמטמיעים גרסה ספציפית של ספריית הספק, Camera2/X מוודאת שהספרייה תואמת לאחור לגרסאות extension-interface
עתידיות.
תאימות קדימה
התאימות לעתיד עם ספריות של ספקים של extensions-interface
גרסאות חדשות יותר תלויה בכם, יצרני הציוד המקורי. אם אתם צריכים תכונות מסוימות כדי להטמיע את התוספים, כדאי להפעיל את התוספים החל מגרסה מסוימת. במקרה כזה, אפשר להחזיר את גרסת extensions-interface
הנתמכת כשגרסת הספרייה של Camera2/X עומדת בדרישות. אם הגרסאות של Camera2/X לא נתמכות, אפשר להחזיר גרסה לא תואמת, כמו 99.0.0, כדי להשבית את התוספים.
איפוס של ספריית הספק
אחרי אימות הגרסה של extensions-interface
שספריית ה-OEM הטמיעה, Camera2/X מתחיל את תהליך האיפוס. השיטה InitializerImpl.init()
מאותתת לספריית ה-OEM שאפליקציה מנסה להשתמש בתוספים.
Camera2/X לא מבצעת קריאות נוספות לספריית ה-OEM (מלבד בדיקת הגרסה) עד שספריית הספק של ה-OEM קוראת ל-OnExtensionsInitializedCallback.onSuccess()
כדי להודיע על השלמת האיפוס.
עליכם להטמיע את InitializerImpl
החל מגרסה 1.1.0 של extensions-interface
. Camera2/X מדלגים על שלב האתחול של הספרייה אם ספריית הספק של ה-OEM מיישמת את 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 ולשלוח בקשות צילום לפי הצורך.
בטבלה הבאה מופיעה ההשוואה:
מאריך בסיסי | Advanced Extender | |
---|---|---|
הגדרות של שידורים | תוקנה תצוגה מקדימה: PRIVATE או YUV_420_888 (אם המעבד קיים) צילום סטילס: JPEG או YUV_420_888 (אם המעבד קיים)
|
ניתן להתאמה אישית על ידי יצרן ציוד מקורי. |
שליחת בקשה לצילום | רק Camera2/X יכול לשלוח בקשות צילום. אפשר להגדיר את הפרמטרים לבקשות האלה. כשהמעבד מסופק לצילום תמונות, Camera2/X יכול לשלוח כמה בקשות צילום ולשלוח את כל התמונות ותוצאות הצילום למעבד. | יינתן לכם מכונה של RequestProcessorImpl כדי להריץ את בקשת הצילום של camera2 ולקבל את התוצאות והתמונה.
Camera2/X מפעיל את |
הוספת ווקים לצינור עיבוד הנתונים של המצלמה |
|
|
מתאים | תוספים שמופעלים ב-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 יש ווקים בכמה מקומות בצינור עיבוד הנתונים של המצלמה. לכל סוג תוסף יש כיתות Extender תואמות ש-OEM צריכים להטמיע.
בטבלה הבאה מפורטות כיתות Extender ש-OEM צריכים להטמיע לכל תוסף:
כיתות הרחבה להטמעה | |
---|---|
לילה | NightPreviewExtenderImpl.java
|
HDR | HdrPreviewExtenderImpl.java
|
Auto | AutoPreviewExtenderImpl.java
|
Bokeh | BokehPreviewExtenderImpl.java
|
ריטוש פנים | BeautyPreviewExtenderImpl.java
|
בדוגמה הבאה אנחנו משתמשים ב-PreviewExtenderImpl
וב-ImageCaptureExtenderImpl
כ-placeholders. מחליפים את השמות האלה בשמות של הקבצים בפועל שאתם מטמיעים.
למפצל הבסיסי יש את היכולות הבאות:
- להחדיר פרמטרים של סשן כשמגדירים את
CameraCaptureSession
(onPresetSession
). - לעדכן אתכם באירועי ההתחלה והסגירה של סשן הצילום, ולשלוח בקשה אחת כדי להודיע ל-HAL על הפרמטרים שהוחזרו (
onEnableSession
,onDisableSession
). - להחדיר פרמטרים של תיעוד לבקשה (
PreviewExtenderImpl.getCaptureStage
,ImageCaptureExtenderImpl.getCaptureStages
). - הוספת מעבדים לתצוגה מקדימה ועדיין לצילום, שיכולים לעבד את מקור הנתונים
YUV_420_888
.
נראה איך Camera2/X מפעיל את extensions-interface
כדי להשיג את שלושת תהליכי האפליקציה שצוינו למעלה.
תהליך האפליקציה 1: בדיקת הזמינות של התוסף
איור 3. תהליך האפליקציה 1 במתאם בסיסי
בתהליך הזה, Camera2/X קורא ישירות לשיטה isExtensionAvailable()
של PreviewExtenderImpl
וגם של ImageCaptureExtenderImpl
בלי לקרוא ל-init()
. שתי הכיתות של Extender צריכות להחזיר את הערך true
כדי להפעיל את התוספים.
לרוב, זהו השלב הראשון שבו אפליקציות בודקות אם יש תמיכה בסוג התוסף במזהה מצלמה נתון, לפני שהן מפעילות את התוסף. הסיבה לכך היא שחלק מהתוספים נתמכים רק במזהי מצלמה מסוימים.
תהליך האפליקציה 2: מידע על השאילתה
איור 4. תהליך האפליקציה 2 במתאם בסיסי
אחרי שבודקים אם התוסף זמין, האפליקציות צריכות לשלוח שאילתה לגבי המידע הבא לפני שהן מפעילות את התוסף.
טווח זמן האחזור לצילום תמונה סטילס: הפונקציה
ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
מחזירה את טווח זמן האחזור לצילום תמונה סטילס, כדי שהאפליקציה תוכל להעריך אם כדאי להפעיל את התוסף בתרחיש הנוכחי.הגדלים הנתמכים של שטח התצוגה המקדימה ושטח הצילום: הפונקציות
ImageCaptureExtenderImpl.getSupportedResolutions
ו-PreviewExtenderImpl.getSupportedResolutions
מחזירות רשימה של פורמטים של תמונות והגדלים הנתמכים לפורמט ולגודל של שטח הצילום.מפתחות בקשה ותוצאה נתמכים: Camera2/X מפעיל את השיטות הבאות כדי לאחזר מההטמעה שלכם את מפתחות הבקשה והתוצאה הנתמכים לצילום:
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
ImageCaptureExtenderImpl.getAvailableCapturetResultKeys
ב-Camera2/X, תמיד קוראים ל-init()
קודם בכיתות Extender האלה לפני ששולחים שאילתה לקבלת מידע נוסף.
תהליך האפליקציה 3: תצוגה מקדימה/צילום סטילס כשהתוסף מופעל (הטמעת HAL)
איור 5. תהליך האפליקציה 3 במתאם בסיסי
בתרשים שלמעלה מוצג התהליך הראשי להפעלת תצוגה מקדימה וצילום תמונות סטילס באמצעות תוסף ללא מעבד. כלומר, ה-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
.
הפונקציה
ImageCaptureExtenderImpl.getCaptureStages
מחזירה רשימה שלCaptureStageImpl
, שבה כל רכיב ממופה למכונה שלCaptureRequest
עם פרמטרים של צילום שנשלחים על ידי Camera2/X. לדוגמה, אם המערכת מחזירה רשימה של שלוש מכונותCaptureStageImpl
, Camera2/X שולחת שלוש בקשות צילום עם פרמטרים תואמים של הצילום באמצעות ה-APIcaptureBurst
.התמונות ומכונות ה-
TotalCaptureResult
שהתקבלו מקובצים יחד ונשלחים ל-CaptureProcessorImpl
לעיבוד.CaptureProcessorImpl
כותב את התמונה של התוצאה (בפורמטYUV_420_888
) למשטח הפלט שצוין בקריאהonOutputSurface()
. אם צריך, Camera2/X ממירה אותם לתמונות JPEG.
תמיכה במפתחות ובתוצאות של בקשות צילום
בנוסף להצגה המקדימה ולצילום במצלמה, אפליקציות יכולות להגדיר זום, פרמטרים של פלאש או להפעיל את התכונה 'הקשה כדי להתמקד'. יכול להיות שהפרמטרים האלה לא תואמים להטמעה של התוסף.
השיטות הבאות נוספו ל-extensions-interface
1.3.0 כדי לאפשר לכם לחשוף את הפרמטרים שההטמעה שלכם תומכת בהם:
- הפונקציה
ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys()
מחזירה את מפתחות הבקשה לתיעוד שנתמכים בהטמעה שלכם. - הפונקציה
ImageCaptureExtenderImpl.getAvailableCaptureResultKeys()
מחזירה את המפתחות של תוצאות הצילום שמכילות את תוצאות הצילום.
אם ה-HAL של המצלמה מעבד את התוסף, Camera2/X מאחזר את תוצאות הצילום ב-CameraCaptureSession.CaptureCallback
. עם זאת, אם המעבד מוטמע, המערכת של Camera2/X מאחזרת את תוצאות הצילום ב-ProcessResultImpl
, והן מועברות ל-method 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
ב-CameraX Extensions API יש תמיכה מפורשת בכל המפתחות שלמעלה עבור תוספים בסיסיים שמטמיעים את הגרסה 1.2.0 או גרסאות קודמות. בגרסה extensions-interface
1.3.0, גם CameraX וגם Camera2 מכבדים את הרשימה המוחזרת ותומכים רק במפתחות שמופיעים בה. לדוגמה, אם תחליטו להחזיר רק את הערכים CaptureRequest#CONTROL_ZOOM_RATIO
ו-CaptureRequest#SCALER_CROP_REGION
בהטמעה של 1.3.0, המשמעות היא שהאפליקציה תתמוך רק בהגדלת התצוגה, ולא תהיה אפשרות להשתמש בהקשה להתמקד, בפלאש ובתיקון החשיפות.
Advanced Extender
'מַרחיב מתקדם' הוא סוג של הטמעה של ספק שמבוססת על Camera2 API.
סוג המכשיר הזה נוסף ב-extensions-interface
1.2.0. בהתאם ליצרן המכשיר, יכול להיות שהתוספים יוטמעו בשכבת האפליקציה, בהתאם לגורמים הבאים:
הגדרת סטרימינג בהתאמה אישית: הגדרת סטרימינג בהתאמה אישית, כמו שידור RAW, או שימוש בכמה שידורים למזהים פיזיים שונים של מצלמות.
יכולת לשלוח בקשות ל-Camera2: תמיכה בלוגיקה מורכבת של אינטראקציה שיכולה לשלוח בקשות צילום עם פרמטרים על סמך התוצאות של בקשות קודמות.
Advanced Extender מספק מעטפת או שכבה ביניים, כך שתוכלו להתאים אישית את הגדרות הסטרימינג ולשלוח בקשות צילום על פי דרישה.
הקבצים להטמעה
כדי לעבור להטמעה של מרחיב מתקדם, השיטה isAdvancedExtenderImplemented()
ב-ExtensionVersionImpl
חייבת להחזיר את הערך true
. לכל סוג תוסף, יצרני ציוד מקורי צריכים להטמיע את המחלקות המתאימות של Extender. קובצי ההטמעה של Advanced Extender נמצאים בחבילה advanced.
כיתות Extender להטמעה | |
---|---|
לילה | advanced/NightAdvancedExtenderImpl.java
|
HDR | advanced/HdrAdvancedExtenderImpl.java
|
Auto | 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()
מחזירה מפה של פורמט התמונה לרשימה של הגדלים הנתמכים לפורמט ולגודל של שטח התצוגה המקדימה. יצרני ציוד מקורי חייבים לתמוך לפחות בפורמט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
למידע נוסף, ראו תמיכה במפתחות ובתוצאות של בקשות צילום.
תהליך האפליקציה 3: תצוגה מקדימה/צילום סטילס כשהתוסף מופעל
איור 10. תהליך האפליקציה 3 ב-Advanced Extender
בתרשים שלמעלה מוצג התהליך הראשי להתחלת התצוגה המקדימה ולצילום תמונות סטילס לסוג 'מגבר מתקדם'. נסביר על כל שלב.
מכונה של
SessionProcessorImpl
הליבה של הטמעת Advanced Extender נמצאת ב-
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
מתחיל לפעול והמסגרת של Camera מפעילה אתonConfigured()
, Camera2/X מפעילה אתSessionProcessorImpl.onCaptureSessionStart()
עם מעטפת הבקשה של Camera2RequestProcessImpl
. ב-Camera2/X מוטמעתRequestProcessImpl
, שמאפשרת להריץ את בקשות הצילום ולאחזר תמונות אם נעשה שימוש ב-ImageReaderOutputConfigImpl
.ממשקי ה-API של
RequestProcessImpl
דומים לממשקי ה-API של Camera2CameraCaptureSession
מבחינת ביצוע הבקשות. ההבדלים הם:- הממשק של היעד מצוין לפי המזהה של המכונה
Camera2OutputConfigImpl
. - היכולת לאחזר את התמונה של
ImageReader
.
אפשר להפעיל את
RequestProcessorImpl.setImageProcessor()
עם מזההCamera2OutputConfigImpl
ספציפי כדי לרשום מכונה שלImageProcessorImpl
לקבלת תמונות.המכונה
RequestProcessImpl
הופכת ללא חוקית אחרי ש-Camera2/X קורא ל-SessionProcessorImpl.onCaptureSessionEnd()
.- הממשק של היעד מצוין לפי המזהה של המכונה
התחלת התצוגה המקדימה וצילום תמונה
בהטמעה של Extender מתקדם, אפשר לשלוח בקשות צילום דרך הממשק
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()
מבצע את הניקוי.
תמיכה בתצוגה מקדימה, בצילום סטילס ובניתוח תמונות
כדאי להחיל את התוסף גם בתרחישים לדוגמה של תצוגה מקדימה וגם בתרחישים לדוגמה של צילום סטילס. עם זאת, אם זמן האחזור גבוה מדי כדי להציג את התצוגה המקדימה בצורה חלקה, תוכלו להחיל את התוסף רק לצילום סטילס.
עבור סוג התוסף 'מרחיב בסיסי', ללא קשר להפעלת התוסף לתצוגה מקדימה, צריך להטמיע גם את ImageCaptureExtenderImpl
וגם את PreviewExtenderImpl
לתוסף נתון. לרוב, אפליקציה משתמשת גם בזרם YUV כדי לנתח את תוכן התמונה, למשל כדי למצוא קודי QR או טקסט. כדי לתמוך טוב יותר בתרחיש לדוגמה הזה, צריך לתמוך בשילוב של מקור נתונים עם תצוגה מקדימה, צילום סטילס ומקור נתונים מסוג YUV_420_888
להגדרת CameraCaptureSession
. כלומר, אם מטמיעים מעבד, צריך לתמוך בשילוב של שלושה מקורות נתונים מסוג YUV_420_888
.
ב-Advanced Extender, Camera2/X מעבירה שלוש פלטפורמות פלט לקריאה SessionProcessorImpl.initSession()
. פלטפורמות הפלט האלה מיועדות לתצוגה מקדימה, לצילום סטילס ולניתוח תמונות, בהתאמה. חשוב לוודא שפני השטח של הפלט של התצוגה המקדימה וצילום הסטילס מציגים את הפלט הנכון. עם זאת, חשוב לוודא שהיא פועלת רק כשהיא לא null, עבור פלט ניתוח התמונה. אם ההטמעה שלכם לא תומכת בשידור של ניתוח התמונות, תוכלו להחזיר רשימה ריקה ב-AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()
. כך מוודאים שפני השטח של הפלט של ניתוח התמונה תמיד יהיו null ב-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
, צריך להשתמש בממשקי ה-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
תיעוד קריאות חוזרות (callbacks) של התקדמות העיבוד
ב-Android מגרסה 14 ואילך, לקוחות של תוסף מצלמה יכולים לקבל קריאות חוזרות (callbacks) לגבי התקדמות של פעולות עיבוד ממושכות של צילומי סטילס. אפליקציות יכולות להציג למשתמשים את ההתקדמות הנוכחית כדי לשפר את חוויית המשתמש הכוללת.
כדי לשלב את התכונה הזו באפליקציות, אפשר להשתמש בקוד הבא:
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
}
}
…
}
כדי לתמוך בקריאות חזרה (callbacks) עם עדכונים על התקדמות העיבוד של התמונות, ההטמעה של ספק התוסף צריכה להפעיל את קריאות החזרה הבאות עם ערך ההתקדמות הנוכחי:
- תוספים בסיסיים:
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
. כדי לוודא שיש תמיכה בכך, מריצים את מודול ה-CTS SurfaceViewExtensionPreviewTest.java
.
סוגי סשנים ספציפיים לספק
התכונה מאפשרת להטמיע תוספים של ספקים ולבחור סוג סשן ספציפי לספק, שיוגדר בסשן הצילום הפנימי של המצלמה במקום ערך ברירת המחדל.
התכונה פועלת לחלוטין בתוך המסגרת וסטאק הספקים, ואין לה השפעה על ממשקי API שגלויים ללקוחות או לציבור.
כדי לבחור סוג סשן ספציפי לספק, צריך להטמיע את הקוד הבא בספריות התוספים:
* ExtenderStateListener.onSessionType()
לתוספים בסיסיים
* Camera2SessionConfigImpl.getSessionType()
לתוספים מתקדמים
היסטוריית הגרסאות של ממשק התוספים
בטבלה הבאה מוצג היסטוריית הגרסאות של ממשק התוסף למצלמה. תמיד כדאי להטמיע את ספריית הספק בגרסה העדכנית ביותר.
גרסה | תכונות שנוספו |
---|---|
1.0.0 |
|
1.1.0 |
|
1.2.0 |
|
1.3.0 |
|
1.4.0 |
|
הטמעת עזר
הטמעות הספריות של ספקי ה-OEM לדוגמה זמינות ב-frameworks/ex
.
advancedSample
: הטמעה בסיסית של Advanced Extender.sample
: הטמעה בסיסית של Basic Extender.service_based_sample
: הטמעה שמראה איך לארח תוספים למצלמה ב-Service
. ההטמעה הזו כוללת את הרכיבים הבאים:oem_library
: ספריית OEM של Camera Extensions ל-Camera2 ול-CameraX Extensions API שמטמיעה אתExtensions-Interface
. הוא פועל כמעבר שמעביר את הקריאות מ-Extensions-Interface
לשירות. הספרייה הזו מספקת גם קובצי AIDL וקלאסיות עטיפה (wrapper) לצורך תקשורת עם השירות.התכונה 'מתחבר מתקדם' מופעלת כברירת מחדל. כדי להפעיל את מרחיב ה-Basic, משנים את הערך של
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. הספרייה של יצרן הציוד המקורי מסומנת כאופציונלית, כך שאפליקציות יכולות לפעול במכשירים שלא כוללים את הספרייה. כשאפליקציה מנסה להשתמש בתוסף מצלמה, המערכת של 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
, כדי לאפשר לשלוח שאילתה לגבי תמיכה בתוספים.
כדי לעשות זאת, מוסיפים את השורה הבאה לקובץ של יצרן המכשיר:
PRODUCT_VENDOR_PROPERTIES += \
ro.camerax.extensions.enabled=true \
אימות
כדי לבדוק את ההטמעה של ספריית הספק של ה-OEM בשלב הפיתוח, תוכלו להשתמש באפליקציית הדוגמה שבכתובת androidx-main/camera/integration-tests/extensionstestapp/
, שמפעילה תוספים שונים של ספקים.
אחרי שמשלימים את ההטמעה, משתמשים בכלי לאימות התוספים למצלמה כדי להריץ בדיקות אוטומטיות וידניות כדי לוודא שספריית הספק הוגדרה בצורה נכונה.
מצב 'סצנה מורחבת' לעומת תוספי מצלמה
כדי להציג את התוסף של אפקט בוקה, בנוסף לחשיפת התוסף באמצעות תוספים למצלמה, אפשר לחשוף את התוסף באמצעות מצב התמונה המורחב, שמופעל באמצעות המקש CONTROL_EXTENDED_SCENE_MODE
.
פרטים נוספים על ההטמעה זמינים במאמר בוקה במצלמה.
למצב התמונה המורחב יש פחות הגבלות בהשוואה לתוספי המצלמה לאפליקציות camera2. לדוגמה, אפשר להפעיל את מצב התמונה המורחבת במכונה רגילה של CameraCaptureSession
שתומכת בשילובים גמישים של שידורים ובצילום של פרמטרים של בקשות. לעומת זאת, התוספים למצלמה תומכים רק בקבוצה קבועה של סוגי סטרימינג, ויש להם תמיכה מוגבלת בפרמטרים של בקשות הצילום.
החיסרון של מצב התמונה המורחב הוא שאפשר להטמיע אותו רק ב-HAL של המצלמה, כלומר צריך לוודא שהוא פועל בכל אמצעי הבקרה האופקיים שזמינים למפתחי האפליקציות.
מומלץ לחשוף את אפקט הבוקה גם באמצעות מצב התמונה המורחב וגם באמצעות התוספים למצלמה, כי יכול להיות שאפליקציות יעדיפו להשתמש בממשק API מסוים כדי להפעיל את אפקט הבוקה. מומלץ להשתמש קודם במצב התמונה המורחב, כי זו הדרך הגמישה ביותר שבה אפליקציות יכולות להפעיל את התכונה 'בוקה'. לאחר מכן תוכלו להטמיע את ממשק התוספים של המצלמה על סמך מצב התמונה המורחב. אם קשה להטמיע את אפקט הבוקה ב-HAL של המצלמה, למשל כי נדרש מעבד פוסט-עיבוד שפועל בשכבת האפליקציה כדי לעבד תמונות, מומלץ להטמיע את התוסף של הבוקה באמצעות ממשק התוספים של המצלמה.
שאלות נפוצות
האם יש הגבלות על רמות ה-API?
כן. זה תלוי בחבילת התכונות של Android API שנדרשת להטמעה של ספריית הספק של ה-OEM. לדוגמה, ExtenderStateListener.onPresetSession()
משתמש בקריאה SessionConfiguration.setSessionParameters()
כדי להגדיר קבוצת בסיס של תגים. הקריאה הזו זמינה רק ברמת API 28 ואילך. פרטים על שיטות ממשק ספציפיות זמינים במאמרי העזרה של API.