Makale Özeti

Bu makalemizde windows mobile ile uygulama geliştirirken kullanabileceğimiz güzel özelliklerden biri olan Microsoft.WindowsMobile.Forms. CameraCaptureDialog adlı class’ın yeteneklerini irdelemeye calışacağız..

Makale

Bu makalemizde windows mobile ile uygulama geliştirirken kullanabileceğimiz güzel özelliklerden biri olan Microsoft.WindowsMobile.Forms. CameraCaptureDialog adlı class’ın yeteneklerini irdelemeye calışacağız..

                Bir çoğunuzun bildiği gibi .NET’in 2 çok önemli hedefi vardı en başta ve bunlara çoktan erişmiş durumda..Nedir bunlar diyecek olursanız 1.pek tabi “entegrasyon “ 2. İse “üretkenlik”..Evet Bill Gates’de .NET ‘in vizyonundan bahsederken özellikle 1. Hedefe dikkat çekmiştir..Bu gün baktığınızda .NET micro device’lardan ( Microsoft .NET Micro Framework) tutunda PC’nin her türlüsüne ve arada kalan tüm cihazlar da dahil olmak üzere mükemmel bir entegrasyon ortamı sunuyor bizlere.Bunların içerisinde arabalarda kullanılan Windows Automotive , web çözümlerimiz , windows tabanlı çözümler, service tabanlı çözümler ve saymakta zorlandığım aklınıza gelen het türlü çözümde mutlaka kullanabileceğiniz bir tool bulabiliyorsunuz..İşte bir zamanlar akıl etmeyi bırakın “nasıl yapilir ki ?“ gibi zor cevaplanabilen bir soruyla kafamızı kaşırken device embed olan bir camera’nın görüntüsünü alıp istediğimiz gibi çözümümüze katabiliyoruz.İsterseniz hep birlikte bu çözümün nasıl gerçekleştirildiğine basit bir örnekle ışık tutalım..

Öncelikle ekteki gibi bir tasarımı yapıyoruz basitçe..Tabi siz istediğinizi yapmakta özgürsünüzJ Burda ihtiyacımız olan 1 adet kamerali ve uzerinde windows mobile işletim sistemi olan bir cihaz.Benim kullandığım Asus’un PDA 526 serisi.Üzerinde 2.0 megapixel kamera ve windows mobile 6.0 işletim sistemi bulunduruyor..Benim darft tasarımım aşağıdaki gibidir..

 

resim1 bulunamadı!

Şimdi ekrandaki nesneleri açıklayacak olursak , Resim Çek adı üstünde ilgili kamerayı handle edip  ( Asus’un kendi camera yazılımını otomatikmen çağırıyor ama bu bir dialog gibi işlem gördüğünden resmi çekip kapattığınızda sorunsuz bir şekilde belirttiğiniz directory’e resmin file olara create edildiğini görüyorsunuz..Her cihazda değişiklik gösterebilir...) ilgili resmi almamızı sağlıyor..

Sarı olarak gördüğümüz label kontrolü ise bizeslayt esnasında görüntülenen resme ait bazı bilgileri veriyor..Dosyanın ismi , ne zaman oluşturulduğu gibi...

Ekranın orta kısmında ki beyaz alanda ise PictureBox kontrolümüz yer alıyor.”Slayt  olarak göster!” kontrolü check durumda ise daha önceden çekilmiş olan resimleri bize bir slayt sunusu halinde veriyor..Tüm bunlara ek olarak bir de Timer controlümüz bulunuyor..

                Kod kısmına geçmeden önce belirtmeliyim ki bazı dosyalar diğerlerinden boyut olarak farklılık göstermesede corrupt gibi görünüp ilgili uygulamayı out of memory exception’ınına düşürerek fail etmesine sebebiyet verebiliyor..Bu durum ilk başta tasarladığım multithread kısımda kendini daha çok gösteriyor..Ben her türlü ihtimale karşı ilgili kod bloğunu silmedim.Eminimki yardımı olacaktır..

        public frmMain()

        {

            InitializeComponent();

            this.MinimizeBox = false;  // ilgili form’un kapatılması durumunda destroy edilmesi için gerekli!Uygulamamız tek form’dan oluşuyor.Eğer bunu set etmezsek uygulamayı device’da kapattığımızı zannedip Visual Studio içerisinden yapacağımız yeni deploy da exception verecektir.Aman Dikkat!

            tmrLive.Enabled = false; // slay için kullanıcak olan timer nesnesini açılışta çalışmayacak şekilde set ediyoruz.

            tmrLive.Interval = 4000; // şimdilik yaklaşık 4 saniye de bir resim değiştirmesini söylüyoruz slayt’da..Bunu isterseniz parametrik hale getirebilirsiniz..

            pBoxMain.SizeMode = PictureBoxSizeMode.StretchImage; // çekilen resmin size’i birebir pBoxMain yani picturebox kontrolümüzle eş değer olmadığından resmi sığdırması gerektiğini ifade ediyoruz..

        }

        public delegate void xyz(); // 2. Bir thread’de resim yüklenecekse kullanılması için..

        static int index = 0; // ilgili directory’de bulunan resimlerden gösterilecek olana ait index numarası..!

        static DirectoryInfo xInfo = null; // directory’de kaç image var. ?

        static FileInfo[] xAllInfo = null; // ilgili img*.* pattern’ine uyan dosyaları get ediyoruz..

        public void CallBefore()

        {

            //this.Invoke(new xyz(CallAfter), new object[] {}); // eğer 2. Thread de uygulamayı devam ettiyor olsaydık .NET 2.0 da yer alan CheckForIllegalCrossThreadCalls adlı property .CF de olmadığından zorunlu bir invoke gerekmekte..Bu kısımları uncheck ederek test etmenizi öneririm....

            CallAfter(); // ilgili directoryden resimleri alıyoruz..

        }

 

        public void CallAfter()

        {

            xInfo = new DirectoryInfo(@"\PHOTOFXV1\CAPTURE");

            xAllInfo = xInfo.GetFiles("IMG*.*");

            for (int i = 0; i < xAllInfo.Length; i++)

            {

                if (index == i)

                {

                    if (!String.IsNullOrEmpty(xAllInfo[i].FullName))

                    {

                        try

                        {

                            pBoxMain.Image = null;

                            pBoxMain.Refresh();

                            pBoxMain.Image = new Bitmap(xAllInfo[i].FullName);

                            pBoxMain.Refresh();

                        }

                        catch

                        {

                            index = 0;

                        }

                    }

                    lblFileInfo.Text = DateTime.Now.ToLongTimeString();

                    lblFileInfo.Refresh();

                    lblFileInfo.Text = xAllInfo[i].Name + " - " + xAllInfo[i].CreationTime.ToShortDateString() + "/" +

                        xAllInfo[i].CreationTime.ToShortTimeString() + Environment.NewLine + xAllInfo[i].Length.ToString(); // ilgili resme ait olan bilgiler ekrana basılıyor..Nedir bunlar resmin kendisi, resmin fiziksel dosya bilgileri vs vs..

                    if (index == xAllInfo.Length-1) // işte en onemli kısımlardan biri.Slayt’ın başarıyla ve ilgili sırayı ( file list içerisinde) kaybetmeden sorunsuzca ekrana ilgili dosyayı gösterebilmesi için ( pBoxMain) gerekli olan static index değişkeni numeric olarak set ediliyor...

                        index = 0;

                    else

                        index++;

                    break;

                }

            }

            tmrLive.Enabled = true; // her bir interval de process time ve interval time çakışmasın diye ilgili olan timer durdurulduğu gibi yeniden başlatılıyor ki yeni resmi gösterebilsin..

        }

        private void btnGetPhoto_Click(object sender, EventArgs e)

        {

            chkSlayt.Checked = false;  // slayt modu kapatılıyor..

            if (!Directory.Exists(@"\PHOTOFXV1"))

            {

                Directory.CreateDirectory("PHOTOFXV1");

                Directory.CreateDirectory(@"PHOTOFXV1\CAPTURE");

            }

            else

            {

                if (!Directory.Exists(@"\PHOTOFXV1\CAPTURE"))

                {

                    Directory.CreateDirectory(@"\PHOTOFXV1\CAPTURE");

                }

            }

            // ilgili resimleri programatic olarak ben sabit versemde klasor bazında siz parametrik yapabilirsiniz...         

            string image_filename = null; // işte ilgili class’ımızın örneğini almaya geldi sıra..

            using (CameraCaptureDialog camera = new CameraCaptureDialog())

            {

                camera.Owner = this; // kamera bileşen bazında kime ait  set ediyoruz..

                camera.Title = "PhotoFX - { "+DateTime.Now.ToShortDateString()+" - "+DateTime.Now.ToShortTimeString()+" }"; // ilgili başlık bilgisi...

                camera.Mode = CameraCaptureMode.Still; // Çekim modu..  video,videoWithaudio opsiyonları da mevcut..

                camera.StillQuality = CameraCaptureStillQuality.Low; // bunun dışında default, high  ve normal opsiyonları da mevcut.Ben az yer kaplamasını istiyorum..

                camera.InitialDirectory = @"\PHOTOFXV1\CAPTURE"; // ve nereye kaydedeceği..!

                if (camera.ShowDialog() == DialogResult.OK)

                {

                    image_filename = camera.FileName; // eğer shot edildiyse yani fotoğraf çekildiyse artık bunu ilgili pBoxMain kontrolünde gösterebiliriz.. dosyalar IMG*.* ismin de ardışıl olarak ilgili directory’e kaydediliyorlar..

                }

                if (!String.IsNullOrEmpty(image_filename))

                {

                    try

                    {

                        pBoxMain.Image = null;

                        pBoxMain.Refresh();

                        pBoxMain.Image = new Bitmap(image_filename);

                        pBoxMain.Refresh();

                    }

                    catch

                    {

                        chkSlayt.Checked = true;

                    }

                }

                camera.Dispose();

            }

        }

        public static byte[] ImageToByteArray(Image image, ImageFormat format) // şu anda kullanmadık ama yazarken kullanırız diye düşündüğüm sonra dan da işinize yarayabilir diye silmediğim faydalı bir metod..Gönderilen Image bilgisini byte array’e çeviriyor..format kısmında jpeg ,png ne verilirse ona gore işlem yapıyor..

        {

            MemoryStream stream = new MemoryStream();

            image.Save(stream, format);

 

            byte[] buffer = stream.GetBuffer();

 

            stream.Close();

            stream = null;

 

            return buffer;

        }

       // tam tersi işlem için gerekli olan metod.

        public static Image ByteArrayToImage(byte[] raw_data)

        {

            MemoryStream stream = new MemoryStream(raw_data.Length);

            stream.Write(raw_data, 0, raw_data.Length - 1);

 

            Bitmap image = new Bitmap(stream);

 

            stream.Close();

            stream = null;

 

            return image;

        }

       //slayt yapılacak sa timer enabled true olmalı..Gereksiz kod yazmamak için tek kalemde denetliyoruz....   

        private void chkSlayt_CheckStateChanged(object sender, EventArgs e)

        {

            tmrLive.Enabled = ((sender as CheckBox).Checked);

        }

 

        private void tmrLive_Tick(object sender, EventArgs e)

        {

            tmrLive.Enabled = false;

            CallBefore(); // işte slayt metodu.. once yukarıda ilgili timer nesnesini stop ediyoruz işlemler konusunda çakışma olmasın..

            //Thread xThread = new Thread(new ThreadStart(CallBefore));

            //xThread.IsBackground = true;

            //xThread.Start(); // eğer 2.thread de devam etseydi kullanacağımız kod parçası..

        }

    }

Tüm ilgili kodları yazdıktan sonra elimizdeki çıktılar aynen aşağıda ki gibi olacaktır..

resim3 bulunamadı! resim4 bulunamadı!

 

Umarım faydası dokunur.. (Stok programlarında ya da custom kendinize ait olan çözümlerde  ( al bunu web servisi  ile db ye yaz ya da gprs ile nete bağlan mail at şu kişiye ya da ya da ... Çözümler beyninizin içinde..))

Başka bir makalede görüşmek dileğiyle..

 

Kaynakça : MSDN

 

Eralp Erat

MVP – Mobile Devices

MCP,MCAD.NET,MCSD.NET

http://www.eralperat.com

HIMS