تنفيذ معاينة

عند إضافة معاينة إلى تطبيقك، استخدِم PreviewView، وهي علامة View يمكن اقتصاصها وتغيير حجمها وتدويرها للعرض المناسب.

يتم بث معاينة الصورة إلى سطح داخل PreviewView عندما يتم تفعيل الكاميرا.

استخدام 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 بعض واجهات برمجة التطبيقات الإضافية لضبط الخصائص، مثل:

وضع التنفيذ

يمكن لـ PreviewView استخدام أحد الأوضاع التالية لعرض معاينة البث على View الهدف:

  • PERFORMANCE هو الوضع التلقائي. يستخدم PreviewView SurfaceView لعرض بث الفيديو، لكنّه يعود إلى TextureView في حالات معينة. يتضمّن SurfaceView سطح رسم مخصّصًا، ما يزيد من فرص تنفيذ مكوّن الأجهزة الداخلي مع تركيب الأجهزة على سطح الفيديو، خاصةً عندما لا تكون هناك عناصر أخرى لواجهة المستخدم (مثل الأزرار) في أعلى فيديو المعاينة. من خلال عرض إطارات الفيديو على تراكب الأجهزة، تتجنب إطارات الفيديو مسار وحدة معالجة الرسومات، ما قد يقلّل من استهلاك طاقة النظام الأساسي ووقت الاستجابة.

  • COMPATIBLE. في هذا الوضع، يستخدم PreviewView واجهة برمجة تطبيقات TextureView، على عكس SurfaceView، التي لا تحتوي على سطح رسم مخصّص. ونتيجة لذلك، يتم عرض الفيديو مع المزج بحيث يمكن عرضه. خلال هذه الخطوة الإضافية، يمكن للتطبيق إجراء معالجة إضافية، مثل تحجيم وتدوير الفيديوهات بدون قيود.

استخدِم PreviewView.setImplementationMode() لاختيار وضع التنفيذ المناسب لتطبيقك. إذا لم يكن وضع PERFORMANCE التلقائي مناسبًا لتطبيقك، سيعرِض نموذج الرمز التالي كيفية ضبط وضع COMPATIBLE:

Kotlin

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

نوع المقياس

عندما تختلف درجة دقة فيديو المعاينة عن أبعاد الفيديو المستهدَف PreviewView، يجب أن يتناسب محتوى الفيديو مع طريقة العرض، سواء من خلال الاقتصاص أو العرض المبسط (مع الحفاظ على نسبة العرض إلى الارتفاع الأصلية). PreviewView توفّر ScaleTypes التالية لهذا الغرض:

  • وFIT_CENTER وFIT_START وFIT_END للعرض الأفقي. ويتم تغيير حجم محتوى الفيديو (إما لأعلى أو أدنى) إلى أقصى حجم ممكن للعرض في هدف 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 مع مراعاة الوضع في أسفل يسار كل منهما.

على سبيل المثال، إليك فيديو مصدر بحجم 640×480 ووجهة بدقة 1920×1080 PreviewView:

صورة تعرض فيديو بحجم 640×480 مقارنةً بمعاينة بدقة 1920×1080

تعرض الصورة التالية عملية تحجيم FIT_START / FIT_CENTER / FIT_END:

صورة تعرض عملية التحجيم FIT_START وFIT_Center وFIT_END

تتم هذه العملية على النحو التالي:

  1. غيّر حجم إطار الفيديو (مع الحفاظ على نسبة العرض إلى الارتفاع الأصلية) باستخدام min(1920/640, 1080/480) = 2.25 للحصول على إطار فيديو متوسّط بدقة 1440×1080.
  2. محاذاة إطار الفيديو 1440×1080 مع PreviewView بدقة 1920×1080
    • بالنسبة إلى FIT_CENTER، يجب محاذاة إطار الفيديو مع منتصف نافذة PreviewView. عمودا البداية والنهاية 240 بكسل في PreviewView فارغان.
    • بالنسبة إلى FIT_START، يجب محاذاة إطار الفيديو مع البداية (الزاوية العلوية اليسرى) من نافذة PreviewView. وتكون الأعمدة النهائية التي تبلغ أبعادها 480 بكسل في PreviewView فارغة.
    • بالنسبة إلى FIT_END، يجب محاذاة إطار الفيديو مع النهاية (أسفل اليسار) من نافذة PreviewView. وتكون أعمدة البداية التي تبلغ 480 بكسل في PreviewView فارغة.

تعرض الصورة التالية عملية تحجيم FILL_START / FILL_CENTER / FILL_END:

صورة تعرض عملية التحجيم FILL_START وFILL_Center وFILL_END

تتم هذه العملية على النحو التالي:

  1. وسِّع نطاق إطار الفيديو باستخدام max(1920/640, 1080/480) = 3 للحصول على إطار فيديو متوسّط بحجم 1920 x 1440 (وهو أكبر من حجم PreviewView).
  2. اقتصاص إطار الفيديو بدقة 1920×1440 ليلائم نافذة PreviewView بدقة 1920×1080.
    • بالنسبة إلى FILL_CENTER، يجب اقتصاص الصورة بحجم 1920×1080 من مركز الفيديو الذي يبلغ مقاسه 1920×1440. لا يظهر أعلى وأسفل 180 سطرًا من الفيديو.
    • بالنسبة إلى FILL_START، يجب اقتصاص الصورة بحجم 1920×1080 من بداية الفيديو الذي تم تغيير حجمه بنسبة 1920×1440. لا تظهر آخر 360 سطرًا من الفيديو.
    • بالنسبة إلى FILL_END، يجب اقتصاص الصورة بحجم 1920×1080 من نهاية الفيديو الذي تم تغيير حجمه بنسبة 1920×1440. لا يظهر أعلى 360 سطرًا من الفيديو.

مراجع إضافية

لمعرفة المزيد من المعلومات عن تطبيق CameraX، يُرجى الاطّلاع على الموارد الإضافية التالية.

درس تطبيقي حول الترميز

  • بدء استخدام CameraX
  • عيّنة تعليمات برمجية

  • نماذج تطبيقات CameraX