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

هنگام افزودن پیش‌نمایش به برنامه‌تان، از 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 را نشان می‌دهد:

کاتلین

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

جاوا

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، تأیید کنید که مقداردهی اولیه آن هنگام ایجاد نما موفقیت‌آمیز بوده است. کد زیر نحوه انجام این کار را نشان می‌دهد:

کاتلین

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

جاوا

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 متصل کنید.

کد زیر نمونه‌ای را نشان می‌دهد:

کاتلین

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

جاوا

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 دارای سطح طراحی اختصاصی است که احتمال بیشتری دارد با هم‌پوشانی سخت‌افزاری توسط ترکیب‌کننده سخت‌افزار داخلی پیاده‌سازی شود، به‌ویژه زمانی که هیچ عنصر میانای کاربر دیگری (مانند دکمه‌ها) در بالای ویدیو پیش‌نمایش وجود نداشته باشد. با رندر کردن با هم‌پوشانی سخت‌افزاری، فریم‌های ویدیو از مسیر GPU اجتناب می‌کنند که می‌تواند مصرف برق و تأخیر پلاتفرم را کاهش دهد.

  • حالت COMPATIBLE. در این حالت، PreviewView از TextureView استفاده می‌کند که برخلاف SurfaceView، سطح طراحی اختصاصی ندارد. درنتیجه، ویدیو با ترکیب کردن رندر می‌شود تا بتواند نمایش داده شود. درطول این مرحله اضافی، برنامه می‌تواند پردازش‌های بیشتری مثل مقیاس‌بندی و چرخاندن ویدیوها را بدون محدودیت انجام دهد.

از PreviewView.setImplementationMode() برای انتخاب حالت پیاده‌سازی مناسب برای برنامه‌تان استفاده کنید. اگر حالت پیش‌فرض PERFORMANCE برای برنامه شما مناسب نیست، نمونه کد زیر نحوه تنظیم حالت COMPATIBLE را نشان می‌دهد:

کاتلین

// 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 را تنظیم می‌کند:

کاتلین

// 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 را نسبت به گوشه پایین سمت راست هرکدام تراز کنید.

برای مثال، در اینجا یک ویدیو منبع ۶۴۰×۴۸۰ و یک مقصد ۱۹۲۰×۱۰۸۰ وجود دارد PreviewView:

تصویر، ویدیویی با وضوح ۶۴۰x۴۸۰ را در مقایسه با پیش‌نمایشی با وضوح ۱۹۲۰x۱۰۸۰ نشان می‌دهد

تصویر زیر فرایند مقیاس‌بندی FIT_START / FIT_CENTER / FIT_END را نشان می‌دهد:

تصویری که فرایند مقیاس‌بندی FIT_START،‏ FIT_CENTER، و FIT_END را نشان می‌دهد

این فرایند به این صورت کار می‌کند:

  1. فریم ویدیو را با min(1920/640, 1080/480) = 2.25 مقیاس‌بندی کنید (نسبت ابعادی اصلی را حفظ کنید) تا فریم ویدیو واسط ۱۴۴۰x۱۰۸۰ را دریافت کنید.
  2. فریم ویدیو ۱۴۴۰×۱۰۸۰ را با PreviewView ۱۹۲۰×۱۰۸۰ تراز کنید.
    • برای FIT_CENTER، فریم ویدیو را با مرکز پنجره PreviewView تراز کنید. ستون‌های ۲۴۰ پیکسلی شروع و پایان PreviewView خالی هستند.
    • برای FIT_START، فریم ویدیو را با شروع (گوشه بالا سمت راست) پنجره PreviewView تراز کنید. ‫۴۸۰ ستون پیکسل پایانی PreviewView خالی است.
    • برای FIT_END، فریم ویدیو را با پایان (گوشه پایین سمت راست) پنجره PreviewView تراز کنید. ‫۴۸۰ ستون پیکسلی اول PreviewView خالی است.

تصویر زیر فرایند مقیاس‌بندی FILL_START / FILL_CENTER / FILL_END را نشان می‌دهد:

تصویری که فرایند مقیاس‌بندی FILL_START،‏ FILL_CENTER، و FILL_END را نشان می‌دهد

این فرایند به این صورت عمل می‌کند:

  1. فریم ویدیو را با max(1920/640, 1080/480) = 3 مقیاس‌بندی کنید تا فریم ویدیو واسطی با اندازه ۱۹۲۰×۱۴۴۰ (که بزرگ‌تر از اندازه PreviewView است) به‌دست آورید.
  2. فریم ویدیو ۱۹۲۰x۱۴۴۰ را برش دهید تا در پنجره ۱۹۲۰x۱۰۸۰ PreviewView جا شود.
    • برای FILL_CENTER، ۱۹۲۰x۱۰۸۰ را از مرکز ویدیو مقیاس‌بندی‌شده ۱۹۲۰x۱۴۴۰ برش دهید. ۱۸۰ خط بالا و پایین ویدیو قابل‌مشاهده نیست.
    • برای FILL_START، ‏۱۹۲۰x۱۰۸۰ را از شروع ویدیو مقیاس‌بندی‌شده ۱۹۲۰x۱۴۴۰ برش دهید. ۳۶۰ خط پایین ویدیو قابل‌مشاهده نیست.
    • برای FILL_END، ‏۱۹۲۰x۱۰۸۰ را از انتهای ویدیو مقیاس‌بندی‌شده ۱۹۲۰x۱۴۴۰ برش دهید. ۳۶۰ خط بالای ویدیو قابل‌مشاهده نیست.

منابع بیشتر

برای کسب اطلاعات بیشتر درباره CameraX، منابع اضافی زیر را ببینید.

Codelab

  • شروع به کار کردن با CameraX
  • نمونه کد

  • برنامه‌های نمونه CameraX