Bagikan melalui


Urutan foto variabel

Artikel ini menunjukkan kepada Anda cara mengambil urutan foto variabel, yang memungkinkan Anda mengambil beberapa bingkai gambar secara berurutan dengan cepat dan mengonfigurasi setiap bingkai untuk menggunakan fokus, flash, ISO, pencahayaan, dan pengaturan kompensasi pencahayaan yang berbeda. Fitur ini memungkinkan skenario seperti membuat gambar Rentang Dinamis Tinggi (HDR).

Jika Anda ingin mengambil gambar HDR tetapi tidak ingin menerapkan algoritma pemrosesan Anda sendiri, Anda dapat menggunakan AdvancedPhotoCapture API untuk menggunakan kemampuan HDR bawaan Windows. Untuk informasi selengkapnya, lihat Pengambilan foto Rentang Dinamis Tinggi (HDR).

Catatan

Artikel ini dibangun berdasarkan konsep dan kode yang dibahas dalam pengambilan foto, video, dan audio Dasar dengan MediaCapture, yang menjelaskan langkah-langkah untuk menerapkan pengambilan foto dan video dasar. Disarankan agar Anda membiasakan diri dengan pola pengambilan media dasar dalam artikel tersebut sebelum beralih ke skenario pengambilan yang lebih canggih. Kode dalam artikel ini mengasumsikan bahwa aplikasi Anda sudah memiliki instans MediaCapture yang telah diinisialisasi dengan benar.

Menyiapkan aplikasi Anda untuk menggunakan pengambilan urutan foto variabel

Selain namespace yang diperlukan untuk pengambilan media dasar, menerapkan pengambilan urutan foto variabel memerlukan namespace berikut.

using Windows.Media.Capture.Core;
using Windows.Media.Devices.Core;

Deklarasikan variabel anggota untuk menyimpan objek VariablePhotoSequenceCapture , yang digunakan untuk memulai pengambilan urutan foto. Deklarasikan array objek SoftwareBitmap untuk menyimpan setiap gambar yang diambil secara berurutan. Selain itu, deklarasikan array untuk menyimpan objek CapturedFrameControlValues untuk setiap bingkai. Ini dapat digunakan oleh algoritma pemrosesan gambar Anda untuk menentukan pengaturan apa yang digunakan untuk mengambil setiap bingkai. Terakhir, deklarasikan indeks yang akan digunakan untuk melacak gambar mana dalam urutan yang saat ini sedang diambil.

VariablePhotoSequenceCapture _photoSequenceCapture;
SoftwareBitmap[] _images;
CapturedFrameControlValues[] _frameControlValues;
int _photoIndex;

Siapkan pengambilan urutan foto variabel

Setelah Anda menginisialisasi MediaCapture Anda, pastikan bahwa urutan foto variabel didukung pada perangkat saat ini dengan mendapatkan instans VariablePhotoSequenceController dari VideoDeviceController tangkapan media dan memeriksa properti Yang didukung.

var varPhotoSeqController = _mediaCapture.VideoDeviceController.VariablePhotoSequenceController;

if (!varPhotoSeqController.Supported)
{
    ShowMessageToUser("Variable Photo Sequence is not supported");
    return;
}

Dapatkan objek FrameControlCapabilities dari pengontrol urutan foto variabel. Objek ini memiliki properti untuk setiap pengaturan yang dapat dikonfigurasi per bingkai urutan foto. Ini termasuk:

Contoh ini akan menetapkan nilai kompensasi paparan yang berbeda untuk setiap bingkai. Untuk memverifikasi bahwa kompensasi paparan didukung untuk urutan foto pada perangkat saat ini, periksa properti Yang didukung dari objek FrameExposureCompensationCapabilities yang diakses melalui properti ExposureCompensation.

var frameCapabilities = varPhotoSeqController.FrameCapabilities;

if (!frameCapabilities.ExposureCompensation.Supported)
{
    ShowMessageToUser("EVCompenstaion is not supported in FrameController");
    return;
}

Buat objek FrameController baru untuk setiap bingkai yang ingin Anda ambil. Contoh ini menangkap tiga bingkai. Atur nilai untuk kontrol yang ingin Anda variasi untuk setiap bingkai. Kemudian, hapus koleksi DesiredFrameControllers dari VariablePhotoSequenceController dan tambahkan setiap pengontrol bingkai ke koleksi.

var frame0 = new FrameController();
var frame1 = new FrameController();
var frame2 = new FrameController();

frame0.ExposureCompensationControl.Value = -1.0f;
frame1.ExposureCompensationControl.Value = 0.0f;
frame2.ExposureCompensationControl.Value = 1.0f;

varPhotoSeqController.DesiredFrameControllers.Clear();
varPhotoSeqController.DesiredFrameControllers.Add(frame0);
varPhotoSeqController.DesiredFrameControllers.Add(frame1);
varPhotoSeqController.DesiredFrameControllers.Add(frame2);

Buat objek ImageEncodingProperties untuk mengatur pengodean yang ingin Anda gunakan untuk gambar yang diambil. Panggil metode statis MediaCapture.PrepareVariablePhotoSequenceCaptureAsync, meneruskan properti pengodean. Metode ini mengembalikan objek VariablePhotoSequenceCapture. Terakhir, daftarkan penanganan aktivitas untuk peristiwa PhotoCaptured dan Stop.

try
{
    var imageEncodingProperties = ImageEncodingProperties.CreateJpeg();

    _photoSequenceCapture = await _mediaCapture.PrepareVariablePhotoSequenceCaptureAsync(imageEncodingProperties);

    _photoSequenceCapture.PhotoCaptured += OnPhotoCaptured;
    _photoSequenceCapture.Stopped += OnStopped;
}
catch (Exception ex)
{
    ShowMessageToUser("Exception in PrepareVariablePhotoSequence: " + ex.Message);
}

Mulai pengambilan urutan foto variabel

Untuk memulai pengambilan urutan foto variabel, panggil VariablePhotoSequenceCapture.StartAsync. Pastikan untuk menginisialisasi array untuk menyimpan gambar yang diambil dan nilai kontrol bingkai dan mengatur indeks saat ini ke 0. Atur variabel status perekaman aplikasi Anda dan perbarui UI Anda untuk menonaktifkan memulai pengambilan lain saat pengambilan ini sedang berlangsung.

private async void StartPhotoCapture()
{
    _images = new SoftwareBitmap[3];
    _frameControlValues = new CapturedFrameControlValues[3];
    _photoIndex = 0;
    _isRecording = true;

    await _photoSequenceCapture.StartAsync();
}

Menerima bingkai yang diambil

Peristiwa PhotoCaptured dinaikkan untuk setiap bingkai yang diambil. Simpan nilai kontrol bingkai dan gambar yang diambil untuk bingkai lalu tingkatkan indeks bingkai saat ini. Contoh ini menunjukkan cara mendapatkan representasi SoftwareBitmap dari setiap bingkai. Untuk informasi selengkapnya tentang menggunakan SoftwareBitmap, lihat Pencitraan.

void OnPhotoCaptured(VariablePhotoSequenceCapture s, VariablePhotoCapturedEventArgs args)
{

    _images[_photoIndex] = args.Frame.SoftwareBitmap;
    _frameControlValues[_photoIndex] = args.CapturedFrameControlValues;
    _photoIndex++;
}

Menangani penyelesaian pengambilan urutan foto variabel

Peristiwa Dihentikan dinaikkan ketika semua bingkai dalam urutan telah diambil. Perbarui status perekaman aplikasi Anda dan perbarui UI Anda untuk memungkinkan pengguna memulai pengambilan baru. Pada titik ini, Anda dapat meneruskan gambar yang diambil dan nilai kontrol bingkai ke kode pemrosesan gambar Anda.

void OnStopped(object s, object e)
{
    _isRecording = false;
    MyPostProcessingFunction(_images, _frameControlValues, 3);
}

Memperbarui pengontrol bingkai

Jika Anda ingin melakukan pengambilan urutan foto variabel lain dengan pengaturan per bingkai yang berbeda, Anda tidak perlu sepenuhnya menginisialisasi ulang VariablePhotoSequenceCapture. Anda dapat menghapus koleksi DesiredFrameControllers dan menambahkan pengontrol bingkai baru atau Anda dapat memodifikasi nilai pengontrol bingkai yang ada. Contoh berikut memeriksa objek FrameFlashCapabilities untuk memverifikasi bahwa perangkat saat ini mendukung flash dan daya flash untuk bingkai urutan foto variabel. Jika demikian, setiap bingkai diperbarui untuk mengaktifkan lampu kilat pada daya 100%. Nilai kompensasi pencahayaan yang sebelumnya ditetapkan untuk setiap bingkai masih aktif.

var varPhotoSeqController = _mediaCapture.VideoDeviceController.VariablePhotoSequenceController;

if (varPhotoSeqController.FrameCapabilities.Flash.Supported &&
    varPhotoSeqController.FrameCapabilities.Flash.PowerSupported)
{
    for (int i = 0; i < varPhotoSeqController.DesiredFrameControllers.Count; i++)
    {
        varPhotoSeqController.DesiredFrameControllers[i].FlashControl.Mode = FrameFlashMode.Enable;
        varPhotoSeqController.DesiredFrameControllers[i].FlashControl.PowerPercent = 100;
    }
}

Membersihkan pengambilan urutan foto variabel

Ketika Anda selesai menangkap urutan foto variabel atau aplikasi Anda ditangguhkan, bersihkan objek urutan foto variabel dengan memanggil FinishAsync. Batalkan pendaftaran penanganan aktivitas objek dan atur ke null.

await _photoSequenceCapture.FinishAsync();
_photoSequenceCapture.PhotoCaptured -= OnPhotoCaptured;
_photoSequenceCapture.Stopped -= OnStopped;
_photoSequenceCapture = null;