הטמעת תצוגה מקדימה

כשמוסיפים תצוגה מקדימה לאפליקציה, צריך להשתמש: PreviewView, שהוא View שניתן לחתוך, לשנות את הגודל שלו ולסובב אותו כדי שהתצוגה תהיה תקינה.

התצוגה המקדימה של התמונה זורמת לפני השטח בתוך PreviewView כאשר המצלמה הופכת לפעילה.

שימוש בתצוגה המקדימה

כדי להטמיע תצוגה מקדימה של CameraX באמצעות PreviewView, צריך לבצע את הפעולות הבאות בשלבים הבאים:

  1. אופציונלי: CameraXConfig.Provider
  2. צריך להוסיף PreviewView לפריסה.
  3. בקשה ProcessCameraProvider
  4. ביצירה של View, מחפשים את ProcessCameraProvider.
  5. צריך לבחור מצלמה ולקשר את מחזור החיים והתרחישים לדוגמה.

יש כמה מגבלות על השימוש ב-PreviewView. כשמשתמשים ב-PreviewView, אי אפשר לבצע אחת מהפעולות הבאות:

  • צריך ליצור SurfaceTexture להגדרה ב-TextureView Preview.SurfaceProvider.
  • מאחזרים את SurfaceTexture מ-TextureView ומגדירים אותו Preview.SurfaceProvider.
  • אפשר לקבל את Surface מ-SurfaceView ולהגדיר אותו Preview.SurfaceProvider.

במקרים כאלה, Preview יפסיק לשדר פריימים אל PreviewView.

הוספת PreviewView לפריסה

בדוגמה הבאה מוצג PreviewView בפריסה:

<FrameLayout
    android:id="@+id/container">
        <androidx.camera.view.PreviewView
            android:id="@+id/previewView" />
</FrameLayout>

בקשת CameraProvider

הקוד הבא מראה איך לבקש CameraProvider:

Kotlin

import androidx.camera.lifecycle.ProcessCameraProvider
import com.google.common.util.concurrent.ListenableFuture

class MainActivity : AppCompatActivity() {
    private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider>
    override fun onCreate(savedInstanceState: Bundle?) {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
    }
}

Java

import androidx.camera.lifecycle.ProcessCameraProvider
import com.google.common.util.concurrent.ListenableFuture

public class MainActivity extends AppCompatActivity {
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
    }
}

בדיקת הזמינות של CameraProvider

לאחר שליחת הבקשה אל CameraProvider, עליך לוודא שהאתחול בוצע בהצלחה בזמן יצירת התצוגה. הקוד הבא מראה איך לעשות זאת:

Kotlin

cameraProviderFuture.addListener(Runnable {
    val cameraProvider = cameraProviderFuture.get()
    bindPreview(cameraProvider)
}, ContextCompat.getMainExecutor(this))

Java

cameraProviderFuture.addListener(() -> {
    try {
        ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
        bindPreview(cameraProvider);
    } catch (ExecutionException | InterruptedException e) {
        // No errors need to be handled for this Future.
        // This should never be reached.
    }
}, ContextCompat.getMainExecutor(this));

כדי לראות דוגמה לפונקציה bindPreview שמשמשת בדוגמה הזו, ראו את הקוד בסעיף הבא.

בחירת מצלמה וקישור מחזור החיים והתרחישים לדוגמה

אחרי שיוצרים ומאשרים את CameraProvider, צריך לבצע את הפעולות הבאות:

  1. יוצרים Preview.
  2. מציינים את האפשרות הרצויה של LensFacing במצלמה.
  3. קישור המצלמה שנבחרה וכל התרחישים לדוגמה למחזור החיים.
  4. מחברים את Preview אל PreviewView.

הקוד הבא מציג דוגמה:

Kotlin

fun bindPreview(cameraProvider : ProcessCameraProvider) {
    var preview : Preview = Preview.Builder()
            .build()

    var cameraSelector : CameraSelector = CameraSelector.Builder()
          .requireLensFacing(CameraSelector.LENS_FACING_BACK)
          .build()

    preview.setSurfaceProvider(previewView.getSurfaceProvider())

    var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview)
}

Java

void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
    Preview preview = new Preview.Builder()
            .build();

    CameraSelector cameraSelector = new CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build();

    preview.setSurfaceProvider(previewView.getSurfaceProvider());

    Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview);
}

הערה: bindToLifecycle() מחזירה Camera לאובייקט. למידע נוסף על שליטה בפלט של המצלמה, כמו זום או חשיפה, ראו פלט מצלמה.

סיימתם להטמיע את התצוגה המקדימה של המצלמה. יצירת האפליקציה ואישור שהתצוגה המקדימה תופיע באפליקציה ותפעל באופן הרצוי.

אמצעי בקרה נוספים ל-PreviewView

CameraX PreviewView מספקת כמה ממשקי API נוספים להגדרת מאפיינים כמו כ:

מצב הטמעה

ל-PreviewView יש אפשרות להשתמש באחד מהמצבים הבאים כדי להציג תצוגה מקדימה של השידור היעד View:

  • PERFORMANCE הוא מצב ברירת המחדל. PreviewView משתמש ב: SurfaceView כדי להציג את הסרטון אבל חוזר ל-TextureView בבמקרים מסוימים. ל-SurfaceView יש משטח שרטוט ייעודי שיש לו סיכוי גבוה יותר שמוטמעות בשכבת-על של חומרה על ידי מרכיב החומרה הפנימי, במיוחד כשאין רכיבים אחרים של ממשק המשתמש (לחצני 'אהבתי') מעל סרטון התצוגה המקדימה. על ידי רינדור באמצעות חומרה שכבת-על, מסגרות וידאו נמנעות מנתיב GPU, דבר שעלול להפחית את כוח הפלטפורמה צריכה וזמן אחזור.

  • COMPATIBLE במצב תצוגה. במצב הזה, PreviewView משתמש ב-TextureView, שלא כמו SurfaceView, אין משטח ייעודי לשרטוט. כתוצאה מכך, סרטון עיבודים שמעורבים במיזוג כדי שיהיה ניתן להציג אותו. בשלב הנוסף הזה, יכול לבצע עיבוד נוסף, כמו התאמה לעומס (scaling) וסיבוב סרטונים ללא הגבלות.

שימוש ב-PreviewView.setImplementationMode() כדי לבחור את מצב ההטמעה שמתאים לאפליקציה שלכם. אם ברירת המחדל מצב PERFORMANCE לא מתאים לאפליקציה שלך. הקוד הבא לא מתאים לאפליקציה שלך דוגמה שמראה איך להגדיר את מצב COMPATIBLE:

Kotlin

// viewFinder is a PreviewView instance
viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE

סוג קנה מידה

כשהרזולוציה של התצוגה המקדימה של הסרטון שונה ממידות היעד PreviewView, תוכן הסרטון צריך להתאים לתצוגה על ידי חיתוך או פורמט letterbox (שמירת יחס הגובה-רוחב המקורי). PreviewView מספק את עוקבים אחרי ScaleTypes למטרה הזו:

  • FIT_CENTER FIT_START, ו-FIT_END לפורמט letterbox. תוכן הסרטון המלא מותאם (למעלה או למטה) גודל מקסימלי שאפשר להציג ביעד PreviewView. עם זאת, למרות שהפריים המלא של הווידאו גלוי, חלק מסוים מהמסך יכול להיות ריק. בהתאם לבחירה שלכם מבין שלושת סוגי קנה המידה האלה, הפריים של הווידאו מתאים למרכז, להתחלה או לסוף של תצוגת היעד.

  • FILL_CENTER FILL_START, FILL_END עבור חיתוך. אם סרטון לא תואם ליחס הגובה-רוחב של PreviewView, רק חלק מהתוכן גלוי, אך הסרטון ממלא את כל PreviewView.

סוג קנה המידה שמוגדר כברירת מחדל ב- CameraX הוא FILL_CENTER. שימוש ב-PreviewView.setScaleType() כדי להגדיר את סוג קנה המידה המתאים ביותר לאפליקציה שלכם. את הקוד הבא הדוגמה מגדירה את סוג קנה המידה FIT_CENTER:

Kotlin

// viewFinder is a PreviewView instance
viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER

התהליך להצגת סרטון כולל את השלבים הבאים:

  1. שינוי גודל הסרטון:
    • לסוגי קנה מידה של FIT_*, צריך לשנות את קנה המידה של הסרטון באמצעות min(dst.width/src.width, dst.height/src.height).
    • לסוגי קנה מידה של FILL_*, צריך לשנות את קנה המידה של הסרטון באמצעות max(dst.width/src.width, dst.height/src.height).
  2. יישור הסרטון המותאם ליעד PreviewView:
    • עבור FIT_CENTER/FILL_CENTER, צריך ליישר למרכז את הסרטון המותאם אישית ואת היעד PreviewView.
    • עבור FIT_START/FILL_START, צריך ליישר את הסרטון המותאם אישית ואת היעד PreviewView ביחס לפינה הימנית העליונה של כל אחד מהם.
    • עבור FIT_END/FILL_END, צריך ליישר את הסרטון המותאם אישית ואת היעד PreviewView ביחס לפינה הימנית התחתונה של כל אחד מהם.

לדוגמה, הנה סרטון מקור בגודל 640x480 ויעד בגודל 1920x1080 PreviewView:

תמונה שמציגה סרטון בגודל 640x480 בהשוואה לתצוגה מקדימה של 1920x1080

בתמונה הבאה רואים FIT_START / FIT_CENTER / FIT_END תהליך ההתאמה לעומס (scaling):

תמונה שמציגה את תהליך ההגדלה של FIT_START, FIT_CENTER ו-FIT_END

התהליך פועל כך:

  1. שינוי גודל הפריים של הסרטון (שמירה על יחס הגובה-רוחב המקורי) באמצעות min(1920/640, 1080/480) = 2.25 כדי לקבל פריים ברמת ביניים של 1440x1080.
  2. מיישרים את הפריים בגודל 1440x1080 עם PreviewView בגודל 1920x1080.
    • עבור FIT_CENTER, צריך ליישר את הפריים של הסרטון למרכז חלון PreviewView. עמודות ההתחלה והסיום של 240 פיקסלים השדות PreviewView ריקים.
    • עבור FIT_START, יישר את הפריים של הסרטון להתחלה (בפינה הימנית העליונה) של החלון PreviewView. עמודות הסיום של 480 פיקסלים בPreviewView ריקות.
    • עבור FIT_END, יישר את פריים הסרטון הסוף (בפינה הימנית התחתונה) של החלון PreviewView. העמודות ההתחלתיות של 480 פיקסלים השדות PreviewView ריקים.

בתמונה הבאה רואים FILL_START / FILL_CENTER / FILL_END תהליך ההתאמה לעומס (scaling):

תמונה שמציגה את תהליך הקנה מידה של FILL_START, FILL_CENTER ו-FILL_END

התהליך פועל כך:

  1. שינוי גודל הפריים באמצעות max(1920/640, 1080/480) = 3 יאפשר לך לקבל מסגרת וידאו בינונית של 1920x1440 (וגדולה יותר מגודל התמונה PreviewView).
  2. חותכים את פריים הווידאו בגודל 1920x1440 כך שיתאים לחלון PreviewView בגודל 1920x1080.
    • בשביל FILL_CENTER, חותכים 1,920x1,080 מהמרכז של 1,920x1,440. סרטון מותאם. לא ניתן לראות את 180 השורות העליונות והתחתונות של הסרטון.
    • ל-FILL_START, צריך לחתוך בגודל 1920x1080 מהתחלה של 1,920x1,440 בקנה מידה וידאו. לא ניתן לראות את השורות התחתונות של הסרטון ב-360 מעלות.
    • ל-FILL_END, צריך לחתוך את התמונה בגודל 1920x1,080 מהסוף של התמונה בגודל 1,920x1,440 וידאו. לא ניתן לראות את 360 השורות העליונות של הסרטון.

מקורות מידע נוספים

למידע נוסף על CameraX, ניתן לעיין במשאבים הנוספים הבאים.

Codelab

  • תחילת העבודה עם CameraX
  • דוגמת קוד

  • אפליקציות לדוגמה של CameraX