C# ile Fotoğraf Galerisi Yapımı

Resim Gösteren bir Uygulama
Bu derste kullanıcıya istediği bir klasördeki resim dosyalarını seçip listeleme ve tek tek veya toplu olarak gösterme imkanı veren bir uygulama geliştireceğiz.
Geliştireceğimiz uygulamanın formu tıpkı Visual Studio’daki bazı pencereler gibi bölmeli olacak ve bölme çizgisi istendiği gibi sola sağa kaydırılabilecektir. Form penceresinin sağ panelinde resim dosyalarını minik kutular içinde toplu halde göstereceğiz; sol panel ise sağ panelde tıklanan bir resmi tek başına gösterecektir. Bu uygulama formunda kullanacağımız bir başka kontrol de araç çubuğu olacaktır.
Formun İlk Adımları
Tabi yine bir C# Windows uygulaması yaratmakla işe başlayacağız. Form dosyasının adını “ResimForm” olarak değiştireceğiz. Bunu yapmak için Solution Explorer penceresinde form simgesi (bir kutu sembolü) ile temsil edilen Form1.cs’in üzerinde farenin sağ düğmesini tıklayıp “Rename” seçeneğini seçip form dosyası için seçtiğimiz ismi yazabiliriz.
Formun tasarım görünümünü ekrana getirip Toolbox’dan önce bir ToolStrip (araç çubuğu) kontrolü (menus/Toolbars kategorisi altında bulunur), sonra da bir SplitContainer (bölmeli panel) kontrolü (bu da Containers kategorisi altında bulunur) seçip form üzerine yerleştirelim. Bu yerleştirme sırası önemlidir, çünkü ancak bu sırayla yerleştirirsek araç çubuğu beklendiği gibi formun üst kısmında sabitlenir, bölünmüş panel de araç çubuğundan geri kalan yeri tamamen kaplıyacak şekilde yayılır. Form aşağıdaki resimdeki gibi gözükecektir; görüldüğü gibi bölünmüş panelin Dock özelliği otomatik olarak Fill olarak seçilmiştir. Bu özelliği değiştirerek formu tam kaplamasını engelleyebiliriz ama bir bölünmüş panelin formu doldurması daha mantıklı olacağından herhangi bir değişiklik yapmamayı tercih edeceğiz.


Şekil 36 Form üzerine bir araç çubuğu ve bölmeli bir panel yerleştirilmesi
Araç çubuğu kontrolü bir çok profesyonel Windows uygulamasında görmeye alışık olduğumuz bir kontroldür. Üzerine düğmeler yerleştireceğimiz bir bant şeklindedir. Bu bant üzerine yerleştireceğimiz bir kaç düğme dosya açma, görünümle ilgili bazı ayarları değiştirme gibi işlemleri gerçekleştirecektir. Bölmeli panel kontrolü de Windows Explorer ve Visual Studio’nun kendisi gibi bir çok popüler uygulamada pencere bölmelerini düzenlemede kullanılmaktadır. Biz de onu form penceresinde resimlerin toplu veya tekgösterildiği panellerin boyutlarını ayarlamak için kullanacağız.
Sonraki adımlara geçmeden önce yeni yerleştirdiğimiz kontrollere istediğimiz isimleri verelim. ToolStrip kontrolüne “AracCubugu”, SplitterPanel kontrolüne ise “BolmeliPanel” ismi verdiğimizi varsayalım. Okuyucularımız kendi istedikleri isimleri koyabilirler; dikkat etmeleri gereken şey şudur ki SplitterPanel kontrolünün panelleri ayrı ayrı isimlendirilemez. Onlar bağlı oldukları kontrolün adına eklenen Panel1 ve Panel2 kelimeleriyle anılacaklardır; örneğin, bizim uygulamamızda sol panel BolmeliPanel.Panel1, sağ panel ise BolmeliPanel.Panel2 adlarını alacaktır.
İlerlemeden önce bir merak etmiş olabilecek okuyucularımız için bir SplitterPanel kontrolünün yalnızca sol-sağ bölmeli değil, yukarı-aşağı bölmeli de olabileceğini belirtmeden geçmeyelim. Forma ilk eklendiğinde SplitterPanel’in Orientation (yönlenim) özelliği Vertical (dikey) seçeneğine ayarlıdır. Bu özellik için Horizontal (yatay) seçeneğini seçseydik, bölmeli panelin ayırma çubuğu yatay olurdu ve panellerden biri yukarıda, biri aşağıda olurdu. Splitter Panel’in başka ilginç özellikleri de vardır; FixedPanel (sabitlenmiş panel) özelliği Panel1 veya Panel2 diye seçilirse o panelin boyutlarının (form boyutlarının değiştirilmesi sırasında) değişmeden kalması sağlanabilir. IsSplitterFixed özelliği ise (True olarak seçilirse) ayıraç çubuğunu sabitlemek içindir. Ne var ki bir SplitterPanel kontrolünün ikiden fazla bölmesi olamaz. İkiden fazla panel isteyen programcılar ya öyle bir kontrolü kendileri sıfırdan tasarlayıp yaratacaklar, ya da bir SplitterPanel’in bölmelerine başka SplitterPanel kontrolleri yerleştirerek alt bölmeler yaratacaklardır.
Bu uygulamanın kullanıcıya resim dosyalarını arayıp bulma yeteneği vermesi için Toolbox’ın Dialogs kategorisinden bir de OpenFileDialog (dosya açma diyalogu) alıp forma yerleştireceğiz. Bu diyalog form üzerine yerleşecek bir kontrol değil de bağımsız bir form olduğu için formun alt tarafında görünecek ve kod içinde yazılan komutlar sayesinde, istendiğinde gözükecektir.
Dosya Açma Yeteneği Eklenmesi
En son eklediğimiz dosya açma diyalogu ekrana getirildiğinde kullanıcıya istediği türden dosyaları tıpkı Windows Explorer uygulamasında olduğu gibi klasörlerden seçme yeteneği verecektir. Bu diyalogun Name özelliğini değiştirerek ona istediğimiz ismi verebiliriz. Bu uygulama için ona “DosyaDlg” ismi verelim. Uygulamamız yalnızca resim dosyalarıyla çalışsın istediğimiz için DosyaDlg diyalogunu yalnızca resim dosyalarını açacak şekilde sınırlayabiliriz. Bunun için onun Filter (filtre) özelliğini değiştirmemiz gerekir. Bu özellik istenen dosya türünün açıklamasını ve uzantısını içeren bir karakter dizisi gerektirir. Yazılışı biraz ilginçtir. Örneğin, DosyaDlg’un yalnızca bmp uzantılı bitmap dosyalarını göstermesi için Filter özelliğine karşılık olarak “Bitmap dosyaları|*.bmp” (tabi ki tırmaklar hariç) yazabiliriz. Yani yalnızca *.bmp diye dosya uzantısını belirtmek yeterli değildir. Dosya türünü adlandıran bir açıklama, bir dikey ayıraç karakteri | konur ve onun ardından dosya uzantısı belirtilir. Başka türden dosyalar da gösterilsin isteniyorsa her değişik dosya türü için yine bir açıklama/uzantı çifti birer dikey ayıraç karakteriyle eklenebilir. Örneğin, bizim uygulamamızın jpg uzantılı JPEG dosyalarını da gösterebilmesi için DosyaDlg’nun filtre özelliği
Bitmap dosyaları|*.bmp|JPEG dosyaları|*.jpg
şeklinde yazılmalıdır. Bu yapıldığında diyalog ekrana geldiğinde o an gösterilen klasördeki bmp uzantılı bitmap dosyalarını gösteriyor olacaktır, ama dosya türü listesinde ikinci seçenek olarak “JPEG dosyaları” seçeneği görülecek, ve o seçenek seçildiğinde jpg uzantılı dosyalar listelenecektir.


Şekil 37 Araç çubuğuna bir düğme eklenmesi
Tabi ki dosya açma diyalogunu eklemekle geliştirdiğimiz uygulamamız hemen dosya açma yeteneği kazanmış olmayacaktır. Bu diyalogu ekrane getirmek için bir takım komutlar yazılması gerekir. Forma ilk eklediğimiz araç çubuğuna (yani ToolStrip konrolüne) ekleyeceğimiz bir düğmenin tıklanmasıyla DosyaDlg’u ekrana getirmek mantıklı bir çözüm olacaktır.
Düğme eklenmesi için araç çubuğunu sol ucuna yakın bir yerde tıklamak yeterli olacaktır. Bunu yaptığımızda çıkan listeden yalnızca düğmeler değil, liste ve metin kutuları vb. gibi başka kontrollerin de bir araç çubuğu kontrolü üzerine yerleştirilebileceğini görürüz. Şimdilik diğerleriyle işimiz olmadığı için onlara hiç bakmayıp bir Button eklemekle yetineceğiz.
Yeni eklediğimiz düğmenin içinde basit bir manzara resmi olacaktır. Bu düğmenin özelliklerinde değişiklik yapmak için onu farenin sağ tuşuyla tıklayabiliriz. Düğmenin DisplayStyle (görünüm şekli ) özelliği “Image” (resim) olarak seçilmiş olduğu için bu düğme resimli bir düğmedir. Bu özelliği “Text” olarak seçerek düğmenin

daha önce formlar üzerine koyduğumuz düğmeler gibi yazılı bir düğme olmasını, veya “ImageAndText” olarak seçerek hem resimli, hem de yazılı olmasını sağlayabiliriz. Ama üzerinde yalnızca resim bulunan bir düğme daha az yer kaplayacağı için DisplayStyle özelliğinin şu andaki değeri bizim için uygundur. Tabi düğme üstündeki resmi değiştirebilirsek hiç fena olmaz.
Yeni eklediğimiz araç çubuğu düğmesinin özellikler tablosundan Image özelliği System.Drawing.Bitmap şeklinde belli bir resim dosyasına karşılık gelmeyen bir jenerik isme sahiptir. Bu ismin yanındaki üç noktalı düğmeyi tıklayıp ekrana gelecek olan diyalogdaki Import düğmesine basarsak, bilgisayar sistemindeki klasörlerden bir resim dosyası seçip düğmenin üzerinde o resmin gözükmesini sağlayabiliriz. Ama biz düğme resmini kendimiz oluşturmak istiyoruz. Bunun için uygulamamızın görsel öğeleri arasına bir resim eklemeliyiz. Görsel öğelere ekleme yapmak için Solution Explorer penceresindeki Properties adlı proje klasöründeki Resources.resx dosyasını tıklayıp aşağıdaki resimdeki gibi bitmap (BMP) türü yeni bir resim dosyası ekleyebiliriz.


Şekil 38 Projeye bir resim dosyası eklenmesi
Yarattığımız resmin adını “imgDosyaAc” koyup Add (Ekle) düğmesine basarsak karşımıza bir renk paletiyle küçük karelere bölünmüş büyük, beyaz, kare şeklinde bir pencere gelir. Bu penceredeki küçük kareler oluşturacağımız resim içindeki pikselleri temsil ederler. Bu pencereyle beraber Visual Studio penceresinde gözükecek olan çizim araç çubuğundan kalem (pencil), fırça (brush) veya boya püskürtücü (airbrush) gibi temsili çizim aletlerini, renk paletinden de istediğimiz renkleri seçerek bir resim oluşturabiliriz. Okuyucularımız hayal güçlerini ve sanatsal yeteneklerini kullanarak dosya açma işini gerçekleşirecek düğmemiz için uygun bir resim hazırlayabilirler. Hazırlanan resim aşağıdaki gibi araç çubuğu düğmesinin resmi olarak atanabilir.


Şekil 39 Bir proje resim dosyasının bir araç çubuğu düğmesine atanması
Bu resim dosyasının geri plan rengi olan beyaz renk araç çubuğu üzerinde sırıtmasın diye düğmenin özellikler listesinden ImageTransparentColor özelliği White olarak seçilmiştir. Bu sayede düğmenin geri planının saydam olması sağlanmıştır.
Son yapılacak iş bu düğmenin Click (tıklama) mesajını yanıtlayacak bir fonksiyon yaratıp bu fonksiyon içine dosya açma diyalogunu ekrana getirecek komutları eklemektir:
private void OnDosyaAcButtonClick(object sender, EventArgs e)
{
DosyaDlg.ShowDialog();
}
Resim Dosyasının Panelde Gösterilmesi
DosyaDlg nesnesine ait ShowDalog() metoduna çağrı yaparak DosyaDlg’un geçici olarak uygulamanın kontrolünü eline alan bağımsız bir diyalog formu şeklinde gözükmesini sağlar. Ama kullanıcının seçeceği resim dosyalarıyla bir şeyler yapacak komutlar koymadığımız için henüz işimiz bitmiş değildir.
Öncelikle, birden fazla resim dosyasını açabilmek istediğimize göre, unutmadan DosyaDlg’un MultiSelect (çoklu seçim) özelliğini True olarak belirlemeliyiz. Sonra, kullanıcının dosya açmaktan vazgeçme olasılığını gözönünde bulunudurmalı ve diyalog sonucu DialogResult.OK değilse –ki değilse kullanıcı OK (Tamam) düğmesine basmamış demektir- dosya açmak için hiç bir girişimde bulunmamalıyız.
Kullanıcının seçtiği resim dosyasının sol panelde gözükmesini istediğimize göre DosyaDlg üzerinde seçilen dosyası sol panelin geri plan resmi olarak atamakla işe başlayabiliriz.


Şekil 40 Dosya açma diyalogundan seçilen resmin panel geri plan resmi olarak atanması
Bunu yapmak için seçilen dosya adını öğrenmemiz gerekir. Bu bilgi DosyaDlg’a ait FileName özelliğinde saklıdır. Ama bu bilgi string, yani bir karakter dizisi türündedir ve onu bir resme dönüştürmek için aşağıdaki gibi bir dönüştürme yapmak gerekir:
private void OnDosyaAcButtonClick(object sender, EventArgs e)
{
if (DosyaDlg.ShowDialog() == DialogResult.OK)
{
BolmeliPanel.Panel1.BackgroundImage =
Image.FromFile(DosyaDlg.FileName);
}
}
Image bir resim dosyasını değil, bir resim öğesini temsil edecek bir değişken türüdür. Bu değişken türüne ait bir fonksiyon olan FromFile() fonksiyonuna dosya ismini argüman olarak verirsek dosyadaki resim hafızaya yüklenir. Yukarıda işte bu şekilde hafızaya yüklenmiş olan resmi sol panelin geri plan resmi (BackgroundImage) olarak atıyoruz.
Resim panelin içine tam sığsın diye sol panelin BackgroundImageLayout (geri plan resmi görünümü) özelliğini Stretch (kenarlara kadar uzat veya sıkıştır) olarak belirlemiştik. O yüzden seçilen resim orantılarını korumamıştır. Adı geçen özellik Zoom olarak seçilmiş olsaydı resim panel içine boyutların orantıları korunacak şekilde sığdırılabilirdi.
Artık en azından sol panelde bir resim gösterebiliyoruz, ama form boyutları değiştirilir veya form ekran üzerinde oradan oraya taşınırsa resmin sık sık kırpıştığı görülecektir. Yani görüntü performansı iyi değildir. Resim göstermek için panelin geri plan resmini değiştirmek yerine panel içine bir ImageBox (resim kutusu) kontrolü yerleştirmek daha iyi sonuç verir. Adına SolPanelResimKutusu diyeceğimiz bir ImageBox kontrolünü sol panele yerleştirip Dock özelliğini Fill olarak seçip paneli doldurmasını sağlayalım. Resmin yukarıdaki resimdeki gibi orantısız gözükmesini engellemek için de SizeMode özelliğini bu kez Zoom olarak seçelim. Sol panelin geri plan resmini değiştiren komutu da aşağıdaki gibi değiştirirsek resim kutumuz çalışıyor olacaktır:
SolPanelResimKutusu.Image = Image.FromFile(DosyaDlg.FileName);
Uygulamayı şimdi çalıştırırsak form boyutlarının değişmesinin resim kutusunu fazla etkilemediğini görürüz. Ne de olsa bu kontrol resim göstermek için tasarlanmıştır.
Resim Dosyalarının Grup Olarak Gösterilmesi
Sol paneldeki resim kutusunu gösterdiği resmi DosyaDlg’da seçilmiş resim olarak belirledik ama DosyaDlg’una çoklu seçme yeteneği verdiğimizi hatırlarsak diyalog üzerinde seçtiğimiz diğer resim dosyalarına ne olduğunu merak edebiliriz. Diyalog üzerinde seçilen tüm dosyaların adları DosyaDlg’una ait FileNames dizisinden öğrenilebilir. Bu dizide dosya adları bulunan tüm resimleri sağ panelde grup halinde göstermek için öncelikle sağ panel içine istenen kontrolleri grup halinde göstermek için tasarlanmış olan bir FlowLayoutPanel (biz bu panel türüne “akış kontrollü grup paneli” veya yalnızca “grup paneli” demeyi tercih edeceğiz) kontrolü yerleştirip bunun sağ paneli doldurmasını sağlarız. Dosya açma düğmesi tıklanınca çağrılan fonksiyonumuzu aşağıdaki gibi düzenlersek seçilen tüm resimler bu grup panelindetopluca gösterilecektir:
private void OnDosyaAcButtonClick(object sender, EventArgs e)
{
if (DosyaDlg.ShowDialog() == DialogResult.OK)
{
SolPanelResimKutusu.Image = Image.FromFile(DosyaDlg.FileName);
if (ResimGrupPaneli.Controls.Count > 0)
{
ResimGrupPaneli.Controls.Clear();
}
int i = 0, n = DosyaDlg.FileNames.Length;
ResimKutulari = new PictureBox[n];
for (i = 0; i < n; i++)
{
ResimKutulari[i] = new PictureBox();
ResimKutulari[i].SizeMode = PictureBoxSizeMode.Zoom;
ResimKutulari[i].Image = Image.FromFile(DosyaDlg.FileNames[i]);
ResimGrupPaneli.Controls.Add(ResimKutulari[i]);
}
}
}
Yeni eklediğimiz FlowLayoutPanel ResimGrupPaneli diye adlandırılmıştır. Dosya açma diyalogunda seçim yapılmışsa ResimGrupPaneli’ne daha önce yerleştirilmiş resim kutuları olup olmadığına bakıyor, varsa onları panelin kontrol listesinden çıkartıyoruz. Daha sonra DosyaDlg’unda seçilen dosya isimlerinin sayısı kadar (bu sayıyı dosya isimleri dizisinin uzunluğuna bakarak buluyoruz) resim kutusu yaratıp onları tek tek grup paneline ekliyoruz.
ResimGrupPaneli’ne yerleştirdiğimiz resim kutusu kontrolleri ResimKutulari adlı bir dizi şeklinde yarılmaktadır. Bu dizinin tanımını yukarıda içeriğini gösterdiğimiz mesaj yanıtlayıcı fonksiyon içine koyabilirdik. Ama o zaman fonksiyonun çalışması bitince dizi kaybolurdu ve panele yerleştirmiş olduğumuz resim kutusu kontrolleriyle iletişimimiz kalmazdı; onların özelliklerini değiştiremezdik, ve onlardan mesaj alamazdık. Bu yüzden dizi tanımı formumuzun kod dosyası içine, ama diğer fonksiyonların dışına konmuştur.
Grup Panelinden Seçilen Resimlerin Sol Panelde Gösterilmesi
Aşağıdaki şekil uygulamamızın son halini gösteriyor. Seçilen dört resim sağdaki grup paneline yerleştirilen dört resim kutusu kontrolü içine yerleştirilmiştir. Uygulamayı son haline getiren okuyucularımız form boyutlarını değiştirirlerse sağ paneldeki resim kutularının, panel daralınca gözden kaybolmayıp daha çoğu alt alta gelecek şekilde yeniden düzenlendiklerini görecektir. Grup panelinin akış kontrolü Visual Studio’nun 2005 sürümüyle kullanıcılara sunulmuş bir yeniliktir ve az çabayla güzel görünümlü görsel uygulamalar hazırlamayı kolaylaştırır.


Şekil 41 Form panelınde resimlerin tek veya toplu görünümü
Şimdi bu grup panelindeki resim kutusu kontrollerine biraz işlerlik kazandıralım. Sağ panelde bir resim tıklanırsa bu resim kutusunun “seçilmiş” olduğunu belli etmek için etrafına bir çerçeve koyalım ve içindeki resmi sol panelde tek başına gösterelim.
Bir resim kutusunun farenin sol tuşuyla tıklanması düğmelerde olduğu gibi Click mesajı yayınlanmasına neden olacaktır. Ama biz sağ paneldeki resim kutularını tasarım görünümünde yerleştirmeyip kod içindeki komutlarla ekliyoruz; o yüzden grup halindeki resim kutuları Click mesajı yayınlarsa yanıtlayacak bir fonksiyonu elle yazmalıyız:
private void OnResimKutusuClick(object sender, EventArgs e)
{
// Eski seçilen kutunun çerçevesini kaldır.
if(SecilenKutu != null)
SecilenKutu.BorderStyle = BorderStyle.None;
// Yeni seçilen kutuyu belirle
SecilenKutu = (PictureBox)sender;
SecilenKutu.BorderStyle = BorderStyle.FixedSingle;
SolPanelResimKutusu.Image = SecilenKutu.Image;
}
Bu mesaj yanıtlayıcı fonksiyonu sağ panele eklenen resim kutularıyla ilişkilendirmek için resim kutularını yaratıp onları grup paneline ekleyen döngüye bir de şu satırı eklemeliyiz:
ResimKutulari[i].Click += new EventHandler(OnResimKutusuClick);
Bunu da yaptıktan sonra sağ panelde hangi resim kutusu seçilmişse onun etrafında bir çerçeve gözükecek ve onun içindeki resim sol paneldeki resim kutusuna aktarılacaktır. Dikkat edilirse seçilmiş olan resim kutusunun kimliğini sender parametresinden alıyoruz ve daha sonra hatırlamak için onun kimliğini fonksiyon içinde tanımlanmış yerel bir değişkende değil, forma ait PictureBox türü bir değişkende saklıyoruz.

Bu linke tıklayarak C# ile Fotoğraf galerisi yapımının anlatıldığı ekitabı indirebilirsiniz.