Makale Özeti

Bu makalede dijital bir fotoğraf makinasıyla çekilmiş bir fotoğrafın kaydı sırasında makina tarafından dosyaya oluşturulan bilgileri dosyadan nasıl okuyacağımızı inceleyeceğiz. Bilgilerin tutulduğu kısma exif dosyası denir. Exif dünyaca bir standarttır ve en son v2.2'si mevcuttur.

Makale

         Merhabalar,

Makale dizimizin bu son kısmında artık resim bşlgilerini okuyacağımız metodu bitirip bir örnek uygulma yazacağız. Şimdi ise metodumuzu yazmaya başlayalım

 
        public void ReadImageProperties()
        {
            foreach (PropertyItem pItem in mImage.PropertyItems)
            {
                if (pItem.Id == 271)
                {
                    mCollection.Add("Camera Manufacturer",this.encoding.GetString(pItem.Value, 0, pItem.Len - 1));
                }
                else if (pItem.Id == 272)
                {
                    mCollection.Add("Camera Model",this.encoding.GetString(pItem.Value, 0, pItem.Len - 1));
                }
                else if (pItem.Id == 274)
                {
                    Int16 val = BitConverter.ToInt16(pItem.Value, 0);
                    if (val >= 1 && val <= 8)
                    {
                        mCollection.Add("Orientation", Enums.GetOrientation(val));
                    }
                    else
                    {
                        mCollection.Add("Orientation", "Unknown");
                    }
                }
                else if (pItem.Id == 282)
                {
                    if (BitConverter.ToInt32(pItem.Value, 4) != 0)
                    {
                        Int32 val = BitConverter.ToInt32(pItem.Value, 0) / BitConverter.ToInt32(pItem.Value, 4);                       
                        mCollection.Add("X Resolution", "1/" + val.ToString());
                    }
                }
                else if (pItem.Id == 283)
                {
                    if (BitConverter.ToInt32(pItem.Value, 4) != 0)
                    {
                        Int32 val = BitConverter.ToInt32(pItem.Value, 0) / BitConverter.ToInt32(pItem.Value, 4);                       
                        mCollection.Add("Y Resolution", "1/" + val.ToString());
                    }
                }
                else if (pItem.Id == 296)
                {
                    Int16 val = BitConverter.ToInt16(pItem.Value, 0);
                    if (val >= 2 && val <= 3)
                    {
                        mCollection.Add("Resolution Unit", Enums.GetResolutionUnit(val));
                    }
                    else
                    {
                        mCollection.Add("Resolution Unit", "Unknown");
                    }
                }
                else if (pItem.Id == 305)
                {
                    mCollection.Add("Software",this.encoding.GetString(pItem.Value, 0, pItem.Len - 1));
                }
                else if (pItem.Id == 306)
                {
                    mCollection.Add("Date/Time",this.encoding.GetString(pItem.Value, 0, pItem.Len - 1));
                }
                else if (pItem.Id == 531)
                {
                    Int16 val = BitConverter.ToInt16(pItem.Value, 0);
                    if (val >= 1 && val <= 2)
                    {
                        mCollection.Add("YCBCr Positioning",Enums.GetYCBCrPositioning(val));
                    }
                    else
                    {
                        mCollection.Add("YCBCr Positioning", "Unknown");
                    }
                }
                else if (pItem.Id == 33434)
                {
                    Int16 val1 = BitConverter.ToInt16(pItem.Value, 0);
                    Int16 val2 = BitConverter.ToInt16(pItem.Value, 4);
                    if (val1>= val2)
                    {
                        val1 /= val2;
                        mCollection.Add("Exposure Time", val1.ToString() + " sec");
                    }
                    val1 = (Int16)(val2/ val1);
                    mCollection.Add("Exposure Time", "1/" + val1.ToString() + " sec");
                }
                else if (pItem.Id == 33437)
                {
                    if (BitConverter.ToInt16(pItem.Value, 4) != 0)
                    {
                        Int16 val1 = (Int16)(BitConverter.ToInt16(pItem.Value, 0) / BitConverter.ToInt16(pItem.Value, 4));
                        Int16 val2 = (Int16)(BitConverter.ToInt16(pItem.Value, 0) % BitConverter.ToInt16(pItem.Value, 4));
                        mCollection.Add("F Number",val1.ToString() + "." + val2.ToString());
                    }
                }
                else if (pItem.Id == 34850)
                {
                    Int16 val = BitConverter.ToInt16(pItem.Value, 0);
                    if (val >= 0 && val <= 8)
                    {
                        mCollection.Add("Exposure Program", Enums.GetExposureProgram(val));
                    }
                    else
                    {
                        mCollection.Add("Exposure Program", "Unknown");
                    }
                }
                else if (pItem.Id == 34855)
                {
                    mCollection.Add("ISO Speed",BitConverter.ToInt16(pItem.Value, 0).ToString());
                }
                else if (pItem.Id ==36864)
                {
                    mCollection.Add("Exif Version", this.encoding.GetString(pItem.Value));
                }
                else if (pItem.Id == 36867)
                {
                    mCollection.Add("Date/Time Original",this.encoding.GetString(pItem.Value, 0, pItem.Len - 1));
                }
                else if (pItem.Id == 36868)
                {
                    mCollection.Add("Date/Time Digitized",this.encoding.GetString(pItem.Value, 0, pItem.Len - 1));
                }
                else if (pItem.Id == 37122)
                {
                    mCollection.Add("Bits per Sample", BitConverter.ToInt16(pItem.Value, 0).ToString());
                }
                else if (pItem.Id == 37380)
                {
                    if (BitConverter.ToInt16(pItem.Value, 4) != 0)
                    {
                        Int16 val1 = (Int16)(BitConverter.ToInt16(pItem.Value, 0) / BitConverter.ToInt16(pItem.Value, 4));
                        Int16 val2 = (Int16)(BitConverter.ToInt16(pItem.Value, 0) % BitConverter.ToInt16(pItem.Value, 4));
                        mCollection.Add("Exposure Bits Value", val1.ToString() + "." + val2.ToString());
                    }
                }
                else if (pItem.Id == 37381)
                {
                    if (BitConverter.ToInt16(pItem.Value, 4) != 0)
                    {
                        
                        Int16 val1= (Int16)(BitConverter.ToInt16(pItem.Value, 0) / BitConverter.ToInt16(pItem.Value, 4));
                        Int16 val2 = (Int16)(BitConverter.ToInt16(pItem.Value, 0) % BitConverter.ToInt16(pItem.Value, 4));
                        mCollection.Add("Max Aperture Value", val1.ToString() + "." + val2.ToString());
                    }
                }
                else if (pItem.Id == 37383)
                {
                    Int16 val = BitConverter.ToInt16(pItem.Value, 0);
                    if (val >= 0 && val <= 6)
                    {
                        mCollection.Add("Metering Mode",Enums.GetMeteringMode(val));
                    }
                    else
                    {
                        mCollection.Add("Metering Mode", "Unknown");
                    }
                }
                else if (pItem.Id == 37384)
                {
                    Int16 val = BitConverter.ToInt16(pItem.Value, 0);
                    if (val >= 0 && val <= 3)
                    {
                        mCollection.Add("Light Source",Enums.GetLightSource(val));
                    }
                    else
                    {
                        mCollection.Add("Light Source", "Unknown");
                    }
                }
                else if (pItem.Id == 37385)
                {
                    Int16 val = BitConverter.ToInt16(pItem.Value, 0);
                    if (val >= 0 && val <= 1)
                    {
                        mCollection.Add("Flash", Enums.GetFlash(val));
                    }
                    else
                    {
                        mCollection.Add("Flash", "Unknown");
                    }
                }
                else if (pItem.Id == 37386)
                {
                    if (BitConverter.ToInt32(pItem.Value, 4) != 0)
                    {
                        Int16 val1 = (Int16)(BitConverter.ToInt32(pItem.Value, 0) / BitConverter.ToInt32(pItem.Value, 4));
                        Int16 val2 = (Int16)(BitConverter.ToInt32(pItem.Value, 0) % BitConverter.ToInt32(pItem.Value, 4));
                        mCollection.Add("Focal Length",val1.ToString() + "." + val2.ToString() + " mm");
 
                    }
                }
                else if (pItem.Id == 40960)
                {
                    mCollection.Add("Flash Pix Version",this.encoding.GetString(pItem.Value));
                }
                else if (pItem.Id == 40961)
                {
                    mCollection.Add( "ColorSpace",BitConverter.ToInt16(pItem.Value, 0).ToString());
                }
                else if (pItem.Id == 40962)
                {
                    mCollection.Add("Width",BitConverter.ToInt16(pItem.Value, 0).ToString() + " pixels");
                }
                else if (pItem.Id == 40963)
                {
                    mCollection.Add("Height",BitConverter.ToInt16(pItem.Value, 0).ToString() + " pixels");
                }
                else if (pItem.Id == 41495)
                {
                    Int16 val = BitConverter.ToInt16(pItem.Value, 0);
                    if (val >= 1 && val <= 7)
                    {
                        mCollection.Add("Sensing Method", Enums.GetSensingMode(val));
                    }
                    else
                    {
                        mCollection.Add("Sensing Method", "Unknown");
                    }
                }
             }
        }
    }
}
          Bu metodumuzda ise makalenin baş kısmında verdiğimiz. Tag Id lerine göre propertyler okunuyor ve belirlediğimiz collection'a atılıyor ancak bu property lerin değerleri byte array seklinde oluyor, bazılarını stringe çevirmek bazılarını ise numeric bir değişken olan Int16 ya çevirmek gerekiyor. Bu geğişken bazı durumlarda direkt property nin değerini temsil ederken bazen ise belirli bir enum'un değerini temsil edebiliyor. Bu değişkeni bazen enumun değerlerini okurken kullanacağımz Enum Classına yazdığımız metodları kullanırken parametre olarak vereceğiz.

         Şimdi ise bir resmi verdiğimizde onun propertylerini veren örnek bir uygulama yazalım.

         Programımızın işleyiş şekli Add butonu ile resim seçilir ve daha sonrasında alt tarafta bulunan listbox tan resim seçildiğinde sağ tarafta bulunan datagride resmin propertyleri gelir. Şimdi bu programın kodlarını inceleyelim.
 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace DigitalImageSummaryReader
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
           
        }
        private Image img;
          Formumuzun koduna bir tane Image tipinden değişken tanımlıyoruz.
 
        private void btnAdd_Click(object sender, EventArgs e)
        {
            ofd.ShowDialog();
            foreach (string str in ofd.FileNames)
            {
                lbxImages.Items.Add(str);
            }
        }
        private void btnRemove_Click(object sender, EventArgs e)
        {
            lbxImages.Items.RemoveAt(lbxImages.SelectedIndex);
        }
          Add buttonuna tıklandığı zaman kullanıcıya Open File Dialog gösteriyoruz, ve burada seçili dosyaları tek tek Listbox'a ekliyoruz. Remove buttonunda ise seçili dosyayı ListBox'tan siliyoruz.
 
        private void lbxImages_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lbxImages.SelectedIndex != -1)
            {
                FillImageProperties(lbxImages.Items[lbxImages.SelectedIndex].ToString());
            }
        }
        private void FillImageProperties(string filePath)
        {
            img = Image.FromFile(filePath);
            ExifInformation eif = new ExifInformation(img);
            eif.ReadImageProperties();
            grvProperties.DataSource = eif.Collection;
            pbxImage.Image = img.GetThumbnailImage(pbxImage.Width, pbxImage.Height, null, System.IntPtr.Zero);
        }
    }
}
          ListBox'ta bulunan seçili item değiştiği zaman FillImageProperties metodunu seçili item'ın dosya pathini parametre olarak veriyoruz vede bu metod biraz önce yazdığımız class'daki metodları  kullanarak Seçili resmin propertylerini getiriyoruz ve DataGridde kullanıcıya gösteriyoruz.



          Bu makalede hepberaber bir resim dosyasının exif dosyasının ne olduğunu,nasıl özellikleri barındırdığını, nasıl okunacağını inceledik ve bunun üzerine bir program yazdık. Resim dosyalarının bilgilerini okuyarak kendinize bir kişisel resim albümü programı yazabilirsiniz veya bir resmin ne zaman çekildiğini biliyorsunuz ancak harddiskinizde nerde olduğunu bilmiyorsanız bir döngü içinde bu propertyleri sorgulayarak bu dosyayı bulabilirsiniz. Daha bunun gibi birçok örnek geliştirmek mümkündür.

oztamer@hotmail.com
tamer.oz@yazgelistir.com
oztamer@hotmail.com
Örnek Kodlar