LockBits
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
-
- Üye
- Mesajlar: 152
- Kayıt: 16 May 2014 11:23
LockBits
Merhabalar, LockBits hakkında sorundan ziyade bir sorum olacak.
function GetDestPointer(Data: BitmapData; x, y: integer):PRGBQuad;
begin
Result := Data.Scan0;
inc(PByte(Result),x*4+Data.Stride*y);
end;
bu kod Pixels[X,Y] ile aynı işi görüyor (benzetme)
burada merak ettiğim neden X * 4 ? 4 ün anlamını merak ediyorum özel bir amacı var mıdır.
birde stride ın açılımını iyi kötü biliyorum fakat bilgi sahibi olan arkadaslarım hocalarım varsa beni daha iyi aydınlatırsa çok sevinirim.
Hepinizden Allah razı olsun.
Hayırlı Ramazanlar.
function GetDestPointer(Data: BitmapData; x, y: integer):PRGBQuad;
begin
Result := Data.Scan0;
inc(PByte(Result),x*4+Data.Stride*y);
end;
bu kod Pixels[X,Y] ile aynı işi görüyor (benzetme)
burada merak ettiğim neden X * 4 ? 4 ün anlamını merak ediyorum özel bir amacı var mıdır.
birde stride ın açılımını iyi kötü biliyorum fakat bilgi sahibi olan arkadaslarım hocalarım varsa beni daha iyi aydınlatırsa çok sevinirim.
Hepinizden Allah razı olsun.
Hayırlı Ramazanlar.
Re: LockBits
- Aynı işi yapıyor bile olsa; ScanLine ile resim satırını array'a alıp üzerinde okuma yapmak, Pixels[X,Y] ile bakmaktan ışık hızı ile yürüme hızı arasındaki fark kadar bir hız farkı yaratıyor.
Bunu fark etmişsindir, başlığı okuyanlar için yenilemek istedim.
- Sorunu yere basan bir hale getirmek için ana kurguyu kod ile belirtmen lazımdı. Buradan ben bir örnek yazayım. Örnek tümüyle senin Stride değeri üzerinden yürüsün diye TYPE tanımını TImageData üzerinden yürüttüm.

- Forma bir TImage koyup içine bir Bitmap resmi yükleyin.
- 100x100'lük bir Bitmap için bu yapı içinde Stride değeri okutulduğunda 400 cevabı döndü.
Şimdi cevabı yazayım :
- Verdiğin formül TImageData'nın ScanLine ile okunmuş pointer üzerinden RGB-BLUE byte'ına denk geliyor. Bunu takip eden (3) byte RGB-GREEN, onu da takip eden (3) byte ise RGB-RED byte'ını alıyor. En son kalan (4) nolu (3) byte ise Alpha byte'ı alır.
- Bunu şahsen şöyle yapıyorum.
şeklinde scanline ile okuyacağım satırı tanımlayıp;
ile bu array tipini bir değişkene bağlayıp
ile ilgili satırı bir batında okuyup geriye satir[x].rgbtRed ile RGB-RED değerini, satir[x].rgbtGreen ile RGB-GREEN değerini satir[x].rgbtBlue ile RGB-BLUE değerini yine aynı şekilde okuyabiliyoruz.

- Sorunu yere basan bir hale getirmek için ana kurguyu kod ile belirtmen lazımdı. Buradan ben bir örnek yazayım. Örnek tümüyle senin Stride değeri üzerinden yürüsün diye TYPE tanımını TImageData üzerinden yürüttüm.

- Forma bir TImage koyup içine bir Bitmap resmi yükleyin.
Kod: Tümünü seç
Type
TImageData = packed record
Width: Integer; //
Height: Integer; //
Stride: Integer; //
PixelFormat: Integer; //
Scan0: Pointer; //
Reserved: Integer; //
end;
PImageData = ^TImageData;
function GetBitmapData(Bitmap: TBitmap): TImageData;
begin
Bitmap.PixelFormat := pf32bit;
Result.Width := Bitmap.Width;
Result.Height := Bitmap.Height;
Result.Stride := Result.Width shl 2;
Result.Scan0 := Bitmap.ScanLine[Result.Height - 1];
Result.PixelFormat := -1; // Windows bitmap format flag
Result.Reserved := 0;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
Var
Data : TImageData;
begin
Data := GetBitmapData( Image1.Picture.Bitmap );
ShowMessage('Stride = ' + IntToStr(Data.Stride) );
end;
Şimdi cevabı yazayım :
- Verdiğin formül TImageData'nın ScanLine ile okunmuş pointer üzerinden RGB-BLUE byte'ına denk geliyor. Bunu takip eden (3) byte RGB-GREEN, onu da takip eden (3) byte ise RGB-RED byte'ını alıyor. En son kalan (4) nolu (3) byte ise Alpha byte'ı alır.
- Bunu şahsen şöyle yapıyorum.
Kod: Tümünü seç
Type
TRGBTripleArray = Array [WORD] of TRGBTriple;
pRGBTripleArray = ^TRGBTripleArray;
Kod: Tümünü seç
Var
satir : pRGBTripleArray;
ile bu array tipini bir değişkene bağlayıp
Kod: Tümünü seç
satir := Bitmap.Scanline[y];
-
- Üye
- Mesajlar: 152
- Kayıt: 16 May 2014 11:23
Re: LockBits
Çok teşekkür ederim * 4 olmasının nedenini anladığımı sanıyorum.
32 bit çalıştığımız için her kanal için atlama yapıyor.- 24 bit çalışşaydık * 3 olacaktı ?
bu stride i sanırım sütün mantığı yerine getirilmiş bir yapı.
ve tam burada ikinci sorunuma çözüm olamıyacağı anlamına geliyor sanırım.
birde padding hakkında bilginiz var mıdır acaba.
// FONKSİYONLAR //
function TForm3.lockBitmap(Bitmap : TGPBitmap) : TBitmapData;
var
r : TGPRect;
begin
r.x := 0;
r.y := 0;
r.width := bitmap.getWidth;
r.height := bitmap.getHeight;
Bitmap.LockBits(r, ImageLockModeRead,
Bitmap.GetPixelFormat, result);
end;
function TForm3.Scanline(BitmapData : TBitmapData; Row : integer) : PRGBQuad;
begin
result := bitmapData.Scan0;
inc(PByte(result), Row * bitmapData.stride);
end;
// BİTİŞ //
BitmapData := lockBitmap(Bitmap);
for Row := 0 to bitmapData.Height - 1 do
begin
theRow := Scanline(BitmapData, Row);
for Col := 0 to BitmapData.Width - 1 do
begin
pixel := theRow^;
// kodlar buraya
inc(theRow);
end;
bu kod sizin de tabirinizle ışık hızında
fakat bir problemim var bu kodda satır satır atlayıp inc ile sütün sütün işliyoruz.
benim istediğim olay tam tersi
yani;
for Col := 0 to bitmapData.Width - 1 do
begin
for Row := 0 to BitmapData.Height - 1 do
begin
pixel := GetDestPointer(BitmapData,Col,Row)^; // BU KOD Satır dan sütüna bazlı yöntemden daha YAVAŞ çalışıyor.
end;
işte tam istediğim bu yani sütündan satıra doğru diğer anlamıyla vertical olarak tarama yapmak istiyorum ama GetDestPointer methodunu kullanmadan da bunu başaramadım sanırım olmuyor stride yapısı yüzünden. bunu yapmamız mümkün müdür hocam.
Saygılar..
32 bit çalıştığımız için her kanal için atlama yapıyor.- 24 bit çalışşaydık * 3 olacaktı ?
bu stride i sanırım sütün mantığı yerine getirilmiş bir yapı.
ve tam burada ikinci sorunuma çözüm olamıyacağı anlamına geliyor sanırım.
birde padding hakkında bilginiz var mıdır acaba.
// FONKSİYONLAR //
function TForm3.lockBitmap(Bitmap : TGPBitmap) : TBitmapData;
var
r : TGPRect;
begin
r.x := 0;
r.y := 0;
r.width := bitmap.getWidth;
r.height := bitmap.getHeight;
Bitmap.LockBits(r, ImageLockModeRead,
Bitmap.GetPixelFormat, result);
end;
function TForm3.Scanline(BitmapData : TBitmapData; Row : integer) : PRGBQuad;
begin
result := bitmapData.Scan0;
inc(PByte(result), Row * bitmapData.stride);
end;
// BİTİŞ //
BitmapData := lockBitmap(Bitmap);
for Row := 0 to bitmapData.Height - 1 do
begin
theRow := Scanline(BitmapData, Row);
for Col := 0 to BitmapData.Width - 1 do
begin
pixel := theRow^;
// kodlar buraya
inc(theRow);
end;
bu kod sizin de tabirinizle ışık hızında

benim istediğim olay tam tersi
yani;
for Col := 0 to bitmapData.Width - 1 do
begin
for Row := 0 to BitmapData.Height - 1 do
begin
pixel := GetDestPointer(BitmapData,Col,Row)^; // BU KOD Satır dan sütüna bazlı yöntemden daha YAVAŞ çalışıyor.
end;
işte tam istediğim bu yani sütündan satıra doğru diğer anlamıyla vertical olarak tarama yapmak istiyorum ama GetDestPointer methodunu kullanmadan da bunu başaramadım sanırım olmuyor stride yapısı yüzünden. bunu yapmamız mümkün müdür hocam.
Saygılar..
Re: LockBits
Rica ederim.
- Bir Bitmap'i binary olarak incelemeyi denerseniz daha kolay anlaşılacaktır. Aslında satır taramaya uygundur. Çünkü sondan başa doğru byte dizileri halinde bir yapısı vardır.
- Sizin yapacağınız en rasyonel işlem: Bitmap büyüklüğünü baz alarak dinamik bir dizi oluşturup, bir defalık tüm byte içeriği veriyi bu diziye okuyup, ondan sonra bu dizi üzerinde sütun takip ederek yapmaktır. Böylece her defasında Bitmap'e başvurmak zorunda kalmazsınız.
- Bir hatırlatma, sizin bu bahsettiğiniz fonksiyon da direkt sütuna bakmaz. Önce satırı okur ondan sonra sütunu bulup geri döndürür. Aynı satırı her defasında yeniden okumak zorunda kalmış olacak ki yavaşlık oluşmuş. Aslında bir okumada gördüğünüz üzere satırdaki sütun kadar veri zaten alınmış oluyor. Siz bunu her sütun için tekrar ederseniz satır sayısı kadar katı yavaşlama aşikardır.
- Bahsettiğim dinamik dizi için resmin büyüklüğü açısından soracak olursanız, 360 derece panorama projemde bir birine stitch edilmiş ve ürün olarak oluşan GigaBit seviyesinde çalışmalarım oldu. Standart 4 GB ramli bir i5 işlemcili bir dizüstü bilgisayarım olduğu halde hiçbir sorun yaşamadım. Bu mihmalde büyüklük sorun teşkil etmiyor diyebilirim.
- Bir Bitmap'i binary olarak incelemeyi denerseniz daha kolay anlaşılacaktır. Aslında satır taramaya uygundur. Çünkü sondan başa doğru byte dizileri halinde bir yapısı vardır.
- Sizin yapacağınız en rasyonel işlem: Bitmap büyüklüğünü baz alarak dinamik bir dizi oluşturup, bir defalık tüm byte içeriği veriyi bu diziye okuyup, ondan sonra bu dizi üzerinde sütun takip ederek yapmaktır. Böylece her defasında Bitmap'e başvurmak zorunda kalmazsınız.
- Bir hatırlatma, sizin bu bahsettiğiniz fonksiyon da direkt sütuna bakmaz. Önce satırı okur ondan sonra sütunu bulup geri döndürür. Aynı satırı her defasında yeniden okumak zorunda kalmış olacak ki yavaşlık oluşmuş. Aslında bir okumada gördüğünüz üzere satırdaki sütun kadar veri zaten alınmış oluyor. Siz bunu her sütun için tekrar ederseniz satır sayısı kadar katı yavaşlama aşikardır.
- Bahsettiğim dinamik dizi için resmin büyüklüğü açısından soracak olursanız, 360 derece panorama projemde bir birine stitch edilmiş ve ürün olarak oluşan GigaBit seviyesinde çalışmalarım oldu. Standart 4 GB ramli bir i5 işlemcili bir dizüstü bilgisayarım olduğu halde hiçbir sorun yaşamadım. Bu mihmalde büyüklük sorun teşkil etmiyor diyebilirim.
-
- Üye
- Mesajlar: 152
- Kayıt: 16 May 2014 11:23
Re: LockBits
valla süpersin hocam Allah razı olsun. kafamda daha netleşti bir de bitmap i binary ı olarak nasıl inceleyeceğim hex editor de mi ?
"Siz bunu her sütun için tekrar ederseniz satır sayısı kadar katı yavaşlama aşikardır."
sanırım
satır sayısı kadar yavaşlama yerine sütün kadar olacaktı ? çünkü o satırdan kaç kere sütün çağırırsam okadar olmaz mı ?
yanlış anlamayın hocam sözlerinizi düzeltmek değil amacım hazıra konmak bana ters birde anlamadığım zaman kendimi öğrenmiş veya programcı olarak saymıyorum bu yüzden düzelttim.
"Siz bunu her sütun için tekrar ederseniz satır sayısı kadar katı yavaşlama aşikardır."
sanırım
satır sayısı kadar yavaşlama yerine sütün kadar olacaktı ? çünkü o satırdan kaç kere sütün çağırırsam okadar olmaz mı ?
yanlış anlamayın hocam sözlerinizi düzeltmek değil amacım hazıra konmak bana ters birde anlamadığım zaman kendimi öğrenmiş veya programcı olarak saymıyorum bu yüzden düzelttim.
Re: LockBits
Haklısın ve doğru algılamışsınız; sütun sayısı kadar yavaşlama diyecektim. Her defasında aynı satırı sütun sayısı kadar baştan okuyoruz ya o bakımdan.anonymousdelphicoder yazdı:valla süpersin hocam Allah razı olsun. kafamda daha netleşti bir de bitmap i binary ı olarak nasıl inceleyeceğim hex editor de mi ?
"Siz bunu her sütun için tekrar ederseniz satır sayısı kadar katı yavaşlama aşikardır."
sanırım
satır sayısı kadar yavaşlama yerine sütün kadar olacaktı ? çünkü o satırdan kaç kere sütün çağırırsam okadar olmaz mı ?
yanlış anlamayın hocam sözlerinizi düzeltmek değil amacım hazıra konmak bana ters birde anlamadığım zaman kendimi öğrenmiş veya programcı olarak saymıyorum bu yüzden düzelttim.
Binary olarak inceleme konusu, hex editör demeyelim de görsel olarak sonucu görebilmeniz için Bitmap'in file header kısmını kesip alıp, resmin binary içeriğinden byte byte olmak üzere iki farklı şekilde okuyup yeni dosya oluşturarak inceleyebilirsiniz. Aksi halde 16'lık düzende 00..FF arasında karakterler size birşey ifade etmeyecektir.
-
- Üye
- Mesajlar: 152
- Kayıt: 16 May 2014 11:23
Re: LockBits
çok sağolun hocam yardımlarınız için tekrardan çok teşekkür ederim