Image nesneleri pixellerden oluşur. Her bir pixeli kalemle kağıda konulan bir nokta gibi düşünebilirsiniz. Image nesnesi tüm bu noktaların oluşturduğu bir görsel sunar bize.
Burada bilinmesi gereken en önemli husus, her bir noktanın (pixelin) üç katmanlı bir yapısının olduğu. Her bir pixel üç renk kombinasyonunun bileşiminden oluşur.
Bu renkler Kırmızı, Yeşil ve Mavi’dir. Yani her bir pixel biraz kırmızı (R(red)), biraz yeşil (G(green)) ve biraz da mavi (B(blue)) renk içerir.
Buradan hareketle image nesnesinin her bir pixelinde RGB renk kombinasyonun sayısal bir değeri bulunmaktadır. Bu sayısal değer her bir renk katmanı için 1 byte lık veriyi saklar.
Yani her bir renk 8 bitlik bir veri ile temsil edilir. Onluk sistemde 2^8 = 256 adet veri demek bu . Yani her bir renk 0-255 aralığında bir sayısal değer ile temsil edilmektedir.
Demek ki her bir pixelin RGB değerleri 0-255 aralığında bir değer alarak o pixelin hangi renk kombinasyonunda görüneceğini belirler.
Kalemle kağıda nokta koyma örneğini vermiştik. Bu örnekten hareketle kalemimizi kırmızı (R), yeşil (G) ve mavi (B) boyamıza tek tek batırıyoruz ve ortaya yeni bir renk karışımı elde ediyoruz ve bu yeni renk karışımını kağıdımıza noktalıyoruz. Bunu yaparken de Kırmızı, Yeşil ve Mavi boyalarımızdan da belli oranlarda faydalanıyoruz. Mesela; 25 tane Kırmızı , 140 tane Yeşil ve 56 tane de Mavi olsun diyoruz. RGB(25,140,56) olmuş oldu. (Burada tane birimini anlaşılsın diye kullandım.) Kalemimizin ucunda RGB(25,140,56) kombinasyonlu yeni bir boya var artık. Kağıdımızın neresini noktalayacağımıza göre Image nesnesi şekil alacaktır.
Image nesnelerin boyutu kaç pixele kaç pixel olarak değerlendirilir. Örneğin 580×640 pixel demek, yatayda 580 adet pixel dikeyde ise 640 adet pixel var demektir. Yani 580×640=371.200 adet pixelden oluşuyor bu Image. Bu 371.200 adet her bir pixelin içinde de RGB renklerinin sayısal değerleri var.
Sanırım konu anlaşıldı biraz.
Herhangi bir programlama dili ile Image nesnelerinin pixellerine erişebiliyoruz ve erişmekle kalmayıp bu pixellerin RGB değerlerini de manipüle edebiliyoruz.
Bunu yapabiliyor olmak bize, Image nesneleri üzerinde istediğimiz değişiklikleri yapmamıza olanak sağlıyor.
Bu yazıda C# programlama dili kullanarak bir Image nesnesi nasıl Grayscale(siyah-beyaz karışık) dönüştürülür ve daha sonra nasıl Monochrome(ya siyah ya beyaz) yapılır onun kodlarını paylaşacağım.
Grayscale yapmak için iki etkili yöntem var. Bunlardan birincisi Average Method denilen ortlama alma metodu, diğeri ise Luminosity Method denilen, Average methoda göre daha parlak bir grayscale elde etmemize olanak sağlayan metod. Ben Luminosity Method’u tercih ettim.
- Average Method: Grayscale= (R+G+B)/3
- Luminosity Method: Grayscale=0.3*R+0.59*G+0.11*B
Monochrome yapmak için ise bir koşul kullandım. 0-255 aralığında ki her bir RGB değerlerinin 0-128 değere sahip olanlarını 0 yap, 129-255 değere sahip olanları 255 yap.
Bunu yaparak artık Image nesnemde ki herbir pixelin RGB değeri ya 0 yada 255 olmuş oldu. Yani Monochrome oldu. Monochrome kelime anlamı olarak eski yunancada mono:tek chrome:renk anlamında tek renkli demek zaten.
Kodlar şu şekilde:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Diagnostics; using System.Drawing.Imaging; namespace WindowsFormsApp16 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { OpenFileDialog dosya = new OpenFileDialog(); dosya.Filter = "Görüntü Dosyası |*.jpg| Görüntü Dosyası|*.bmp"; dosya.FilterIndex = 1; dosya.RestoreDirectory = true; dosya.CheckFileExists = false; dosya.Title = "Aktarım Yapılacak Görüntü Dosyası Seçiniz.."; dosya.Multiselect = false; string DosyaYolu = ""; if (dosya.ShowDialog() == DialogResult.OK) { DosyaYolu = dosya.FileName; } else { return; } pictureBox1.Load(DosyaYolu); pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; label1.Text = pictureBox1.Image.Width.ToString() + "x" + pictureBox1.Image.Height.ToString(); } private void button2_Click(object sender, EventArgs e) { Stopwatch watch = new Stopwatch(); watch.Start(); Bitmap Resim; Bitmap ResimC; int R = 0; int G = 0; int B = 0; int R2 = 0; int G2 = 0; int B2 = 0; Resim = new Bitmap(pictureBox1.Image); ResimC = new Bitmap(pictureBox1.Image.Width, pictureBox1.Image.Height); for (int i = 0; i < pictureBox1.Image.Width; i++) { for (int j = 0; j < pictureBox1.Image.Height; j++) { Color renk = Resim.GetPixel(i, j); R = renk.R; G = renk.G; B = renk.B; //Grayscale yapıyoruz R2 = Convert.ToInt32(0.3 * R + 0.59 * G + 0.11 * B); G2 = Convert.ToInt32(0.3 * R + 0.59 * G + 0.11 * B); B2 = Convert.ToInt32(0.3 * R + 0.59 * G + 0.11 * B); //Grayscaleden monochrome geçiş yapıyoruz R2 = R2 < 128 ? 0 : 255; G2 = G2 < 128 ? 0 : 255; B2 = B2 < 128 ? 0 : 255; Color renkM = Color.FromArgb(R2, G2, B2); ResimC.SetPixel(i, j,renkM); } } pictureBox2.Image = ResimC; pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage; watch.Stop(); label2.Text = watch.Elapsed.TotalMilliseconds.ToString() + " ms"; } private void button3_Click(object sender, EventArgs e) { Bitmap Resim = new Bitmap(pictureBox2.Image); SaveFileDialog dialog = new SaveFileDialog(); if (dialog.ShowDialog() == DialogResult.OK) { Resim.Save(dialog.FileName, ImageFormat.Jpeg); } else { return; } } } }
Ben bir görsel üzerinde gerçekleştirdiğim sonuçları burada paylaşayım.
Projenin tamamını da buradan indirebilirsiniz.