IRCForumları - IRC ve mIRC Kullanıcılarının Buluşma Noktası
  sohbet

Yeni Konu aç Cevapla
 
LinkBack Seçenekler Stil
Alt 09 Eylül 2013, 22:21   #1
Çevrimiçi
Kullanıcıların profil bilgileri misafirlere kapatılmıştır.
IF Ticaret Sayısı: (0)
IF Ticaret Yüzdesi:(%)
C++ BMP Okuma




Evet görüntü işlemeye devam ediyoruz.BMP ile ilgili teorik bilgileri bir önceki yazımda vermiştim.Bu yazımda ise C++ ile bir BMP resmini açıp,resme ait temel bilgilere erişmeye çalışacağız.Yazacağımız kodda bir BMP resmi binary olarak açılacak ve imleç konumlandırılarak resme ait bilgiler okunacaktır.Görüntü işleme kütüphanesi projesine de ufak ufak başladığımdan yazacağımız programı fonksiyon olarak vermeye karar verdim.Fonksiyon *filename adında bir dosya yolu ile çağrılır.Bu dosya yolu ifstream fonksiyonu kullanılarak binary olarak açılır.BMP resminde daha önceki yazımda söylediğim üzere ilk 2 bayt BM karakterlerini tutar.Read fonksiyonu ile 'BM' karakterleri bftype adlı değişkene atanır.Bu değişken okuduğumuz dosyanın bir bmp resmi olup olmadığını anlamamıza yarayacak olduğundan hatasız bir program için mutlaka okunup içeriği incelenmelidir.Bundan sonra seekg fonksiyonu ile imleç istenilen adrese konumlandırılarak içerisindeki değer okunur ve ilgili değişkene atanır.Resimdeki gerekli büyüklükler okunduktan sonra
imleç renklerin başlangıç adresi olan bfoffset adresine yerleştirilir.Bu değer BMP resmi içerisinde 10.baytta yazılıdır(24 bit BMP için bfoffset=54).İmleç yerleştirildikten sonra iç içe 2 for döngüsü ile resim boyu ve eni boyunca pixel pixel taranır ve okunan her pixel değeri oluşturulan matrise atanır.Bu aşamadan sonra artık elimizde resim değil,içerisinde red,green,blue ve alpha değerlerini tutan 4 adet matris vardır ve yapılacak tüm işlemler bu matris üzerinden yapılır.

NOT: RGB değerlerini okurken her satırın sonunda imleci kaldığı yerden padding değeri kadar kaydırdığımızı farketmişsinizdir.Bunun nedeni daha önce bahsetmediğim BMP formatına ait Padding kavramı.Bmp formatı bir satırın uzunluğunu 4 bayt ve katları uzunluğunda olmasını ister.Mesala biz 3x3 pixellik bir resmi kaydetmeye çalıştığımızda her pixel için 3 bayt(RGB) tutulduğundan(24-BMP) bir satırın uzunluğu 3*3=9 bayt olacaktır.Ancak BMP her satırın 4 bayt ve katı uzunlukta olması için 9 bayta 3 bayt daha ekler.Eklenen bu baytlar 00 00 00 içeriklidir ve padding olarak adlandırılır.Eğer okuma yaparken bu baytlarıda renk değeri olarak okursak ciddi bir hata yapmış oluruz.

Kod:   Kodu kopyalamak için üzerine çift tıklayın!
bool BMPF::openbmp(char *filename) { ifstream bmp(filename,ios::binary); bmp.read((char*)&header.bftype,2); bmp.seekg(2,ios::beg); bmp.read((char*)&header.bfsize,4); bmp.seekg(10,ios::beg); bmp.read((char*)&header.bfoffset,4); bmp.seekg(18,ios::beg); bmp.read((char*)&bminfo.width,4); bmp.seekg(22,ios::beg); bmp.read((char*)&bminfo.height,4); bmp.seekg(28,ios::beg); bmp.read((char*)&bminfo.bppixel,2); int i=0,j=0; byte padding=4-(3*bminfo.width)%4; if(padding==4) { padding=0; } bmp.seekg((int)header.bfoffset,ios::beg); for(j=bminfo.height-1;j>=0;j--) { for(i=0;i< bminfo.height;i++) { bmp.read((char*)&pixels[i][j],3); } bmp.seekg(padding,ios::cur); } bmp.close(); return true; }

Bu kod çalıştırılacak olursa zaman açısından çokta verimli olmadığı görülür.Çünkü bu kodla her bir pixeli tek tek okuduk.(Mavi ile yazılı satırlarda)Yani resmi bir cümle olarak düşünecek olursak her bir kelimeden sonra durarak okuduk.Buda bizi yavaşlattı.Şimdi bir tampon tanımlayalım ve tüm satırı bir kerede okuyalım.24 bit BMP için bir satırdaki toplam byte sayısı=genişlik*3+padding kadardır.(Her R,G,B için bir byte).Yani bir defada bu kadar byte'lık bir alan okuyacağız.

Kod:   Kodu kopyalamak için üzerine çift tıklayın!
int buffersize=bminfo.width*3+padding; byte *buffer; buffer=new byte [buffersize]; j=bminfo.height-1; while(j>-1) { bmp.read((char*)buffer,buffersize);

Artık resim matrisimizin bir satırı buffer adlı adreste. Bu adresdeki değerleri pixels[m][n] matrisine almak için memcpy(1,2,sayi) adlı fonksiyonu kullanacağız.Bu fonksiyon ile 2. bellek bölgesinden sayi kadar byte 1.bellek bölgesine kopyalanır.

Kod:   Kodu kopyalamak için üzerine çift tıklayın!
for( i=0 ; i < bminfo.width ; i++ ) { memcpy( (char*) &(pixels[i][j]), buffer+3*i, 3 ); } j--; } delete [] buffer;

Her satır için işlem tekrar edildikten sonra tüm veiler pixels[m][n] matrisimize yazılmış olur.Artık tampon dosyamız ile işimiz kalmadığından buffer ı silebiliriz.Bu düzenleme sonrasında kod yeniden çalıştırılırsa bir 5100x3300 bir resim için 120 kat daha hızlı çalıştığı görülür.Resmin genişliği arttıkça bu oranda artacaktır.

Alıntı

 
Alıntı ile Cevapla

IRCForumlari.NET Reklamlar
sohbet odaları sohbet odaları Benimmekan Mobil Sohbet
Cevapla

Etiketler
bmp, okuma


Konuyu Toplam 1 Üye okuyor. (0 Kayıtlı üye ve 1 Misafir)
 
Seçenekler
Stil

Yetkileriniz
Konu Acma Yetkiniz Yok
Cevap Yazma Yetkiniz Yok
Eklenti Yükleme Yetkiniz Yok
Mesajınızı Değiştirme Yetkiniz Yok

BB code is Açık
Smileler Açık
[IMG] Kodları Açık
HTML-Kodu Kapalı
Trackbacks are Kapalı
Pingbacks are Açık
Refbacks are Açık


Benzer Konular
Konu Konuyu Başlatan Forum Cevaplar Son Mesaj
Düşünce Okuma Nedir - Düşünce Okuma Teknikleri Zen Kişisel Gelişim 0 28 Kasım 2012 15:46
Türkler ve kitap okuma oranı - Türkiye ve dünyada kitap okuma oranları araştırması. Sevda Türkçe 1 29 Eylül 2012 20:40
Şiir Okuma Yöntemleri ve Şiir Okuma Teknikleri.. IF Şiir, Hikaye ve Güzel Sözler 0 21 Ocak 2012 04:51
TCL Log. & Okuma karniyarik Eggdrop, NeoStats, BNC 3 27 Şubat 2010 22:13