25 Haziran 2010 Cuma

Silverlight 4 ile Web Kamerası ile görüntü (CaptureSource Nesnesi)

Merhaba arkadaşlar. Bir internet sayfasının bilgisayarınızdaki kamera ve mikrofona ulaşması bugüne kadar kolay olmayan bir durumdu. Ancak Silverlight 4.0 bu işi çok kolaylaştırmış. Aşağıdaki gibi bir uygulama yapacağım.

Projeye başlarken User Control üzerine bir adet rectangle, 4 tane buton, 2 adet combobox ve bir tane de image controlü ekliyoruz. Bunlardan image controlü Exp. Blend'de toolbox'da görünmez. Toolbox'ın en altındaki ">>" butonu ile genişlettiğimiz Assest menüsünden "Locations" sekmesinin altında "image" kontrolünü bulup seçebiliriz.
Seçtiğimiz "image" kontrolünü istediğimiz yere çizip eklemiş oluruz. Yukarıdaki arayüzde sağ üst tarafta bulunan küçük resim "image" kontrolümüzdür.

Arayüzü hazırladıktan sonra yapmamız gereken şey tüm kontrollerimize isim vermek. C# yada VB bilenler isimlendirmede bazı kısaltmalara alışkındırlar. Mesela "btnBasla", "Başla" butonuna verdiğim isim. Bu şekilde "cboVideo", "cboAudio", "btnResim", "imgCapture", "recVideo" gibi isimleri kullandım. Sizler de istediğiniz isimleri kullanabilirsiniz, yeter ki isimlendirmede boşluk ve noktalama karakterleri kullanmayın!

İşim gerisi kod yazmak. Kod kısmına "Önce Kamera ve mikrofon listesi oluştur" butonu ile başlayacağız. Butonu seçip Properties penceresinde "Event" sekmesine geçin ve "Click" eventine çift tıklayın. Kod penceresi (MainPAge.xaml.cs) açılacaktır. Aşağıda bu buton için gerekli kodları yazıyorum. Açıklaması hemen altında.

private void btnKameraListesiOlustur_Click(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
// Kamera ve mikrofon erişimi için izin iste
if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
{
// Combobox'lara aygıtları yükle
// Kameraları combobox'a yükle
cboVideo.ItemsSource = CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices();
cboVideo.DisplayMemberPath = "FriendlyName";
if (cboVideo.Items.Count > 0)
cboVideo.SelectedIndex = 0;

// Mikrofonları combobox'a yükle
cboAudio.ItemsSource = CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices();
cboAudio.DisplayMemberPath = "FriendlyName";
if (cboAudio.Items.Count > 0)
cboAudio.SelectedIndex = 0;
}
}

Burada ilk if ifadesi ile kullanıcıya "kameralarına erişim izni veriyor musun? " sorusunu soruyoruz. Bu Silverlight 4 ile gelen yeni bir özellik.
Eğer kullanıcı ever derse kodların devamında makinede tanımlı kamera ve mikrofonların listesini alıp combobox'lara dolduruyoruz. Eğer kamera ve mikrofon varsa, ilk elemanları seçili duruma getiriyoruz. Kullanıcı daha sonra combobox'dan istediği kamera ve mikrofonu seçebilir.

Sıra Başla ve Bitir butonlarında. Ancak bir de asıl yakalama işini (capture) yapacak nesnemizi tanımlıyoruz. Global alanda yaptığımız bu tanımlada CaptureSource tipinde bir nesne oluşturuyoruz.

// CaptureSource tipindeki nesnemizi tanımlıyoruz.
CaptureSource objYakalamaNesnesi = new CaptureSource();
private void btnBasla_Click(object sender, System.Windows.RoutedEventArgs e)
{
// eğer zaten başladıysa durdur
if(cboVideo.Items.Count == 0)
{
MessageBox.Show("Kamera bulunamadı");
return;
}
if (objYakalamaNesnesi.State == CaptureState.Started)
objYakalamaNesnesi.Stop();
// seçilen aygıtları al
objYakalamaNesnesi.VideoCaptureDevice = (VideoCaptureDevice)cboVideo.SelectedItem;
objYakalamaNesnesi.AudioCaptureDevice = (AudioCaptureDevice)cboAudio.SelectedItem;
// goruntuyu önce hafızaya al
VideoBrush KameraGoruntusu = new VideoBrush();
KameraGoruntusu.SetSource(objYakalamaNesnesi);
// goruntuyu sonra ekranda bir rectangle elemanına bağla
recVideo.Fill = KameraGoruntusu;
// başlat
objYakalamaNesnesi.Start();
}

Başla butonu tıklandığında yaptığımız iş, CaptureSource tipineki "objYakalamaNesnesi" nesnemize seçilen kamera ve mikrofonu atamak, ardından görüntüyü rectangle kontrolüne bağlamak ve son olarak yakalamayı başlatmak.

Aşağıda Bitir butonu için gerekli kodlar var.

private void btnBitir_Click(object sender, RoutedEventArgs e)
{
// Eğer kamera çalışıyorsa durdur
if (objYakalamaNesnesi.State != CaptureState.Stopped)
objYakalamaNesnesi.Stop();
}


.State özelliği, yakalama nesnemizin o anda ne yaptığını kontrol eden bir özellik. Eğer durmamışsa durdurmak için önce kontrol ediyoruz.

Son olarak resim yakalamayı yapalım. Bunun için hem "Resim" butonuna hem de bundan önce resim yakalama olayının yaratılmasına ihtiyacımız var. Aşağıda Resim_Click() metodu, GoruntuKaydedildi() eventi, ve bu event'i CaptureSource tipindeki nesnemize bağlamak için UserControl_Loaded() eventlerine kod yazıyoruz:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
// Yakalama ogjesine Event ekliyoruz
objYakalamaNesnesi.CaptureImageCompleted += new EventHandler<captureimagecompletedeventargs>(GoruntuKaydedildi);
}

private void GoruntuKaydedildi(object sender, CaptureImageCompletedEventArgs e)
{
//Hafızadaki resmi ekrandaki imgCaptured kontrolüne getir
imgCaptured.Source = e.Result;
}

private void btnResim_Click(object sender, RoutedEventArgs e)
{
//Resim çek
if(objYakalamaNesnesi.State == CaptureState.Started)
objYakalamaNesnesi.CaptureImageAsync();
}

Bu metodlardan UserControl_Loaded() ilk başta çalışıyor ve yakalama objesine GoruntuKaydedildi() olayını bağlıyor. Bunda sonra kullnıcı Resim butonuna tıkladığında CaptureImageAsync() metodu ile o andaki görüntü karesini hafızaya aktarıyor. Bu sırada GoruntuKaydedildi()eventi tetiklendiği için, bu event içine program geliyor. "e.Result" nesnesi ile ekrandaki "imgCapture" resim kutusuna resmi aktarıyoruz.

Hepsi bu kadar.
Bu uygulamayı Tim Heuer'in bloğundan uyarlayarak yaptım. (http://timheuer.com)

1 yorum:

  1. bu resmi savefile dialogla kaydetmek mümkün mü ?
    yANİ save file dialog a yonlendirsem imgCapture içeriğini kaydedebilirmiyim ?

    YanıtlaSil