BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Copy pBytes:Pointer rgb to Graphics32 canvas, fastest way?

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Multimedia
View previous topic :: View next topic  
Author Message
Whome
Guest





PostPosted: Sun Jan 21, 2007 9:11 am    Post subject: Copy pBytes:Pointer rgb to Graphics32 canvas, fastest way? Reply with quote



http://koti.mbnet.fi/akini/delphi/dspack/
file: SampleGrabber.zip

I have edited DSPACK samplegrabber demo to use device capture and
Graphics32 image canvas.

I am not sure about how to use "pBuffer: Pointer" variable most
effective way. See example, now I increment pointer one byte when
traveling through a image size.

Is there a way to cast pBuffer to byte array, without copying a data.
This should create no extra copying 'cause callback method is called
25-50 times per seconds.

What I do here is reading RGB 24-bit pixels and convert to ARGB 32-bit
pixels.

// callback: DirectShow calls this on each video frame
procedure TForm1.SampleGrabberBuffer(sender: TObject; SampleTime: Double;
pBuffer: Pointer; BufferLen: Integer);
var
idx: Integer;
a, r, g, b: Byte;
pb: PByte;
P: PColor32Array;
begin
if CallBack.Checked then begin
Image.Canvas.Lock; // to avoid flickering
G32.Bitmap.Lock;
G32.BeginUpdate;
try
// 1: Use Delphi Image
SampleGrabber.GetBitmap(Image.Picture.Bitmap, pBuffer, BufferLen);

// 2: Use Graphics32 Image
// Logitech webcam RGB24 352x288, 24 bits = 304128 bufferlen
// NOTE: source byte format may change depending on camera
// or "Play File..." file codec being used.
// For now hardcode this format.

prevBufferLen := BufferLen;
P := G32.Bitmap.Bits;

pb := PByte(pBuffer);
Dec(pb, 1); // go back one step, we +1 inc inside for loop
for idx := 0 to G32.Bitmap.Width * G32.Bitmap.Height - 1 do begin
// Logitech gives bytes as BGR (mirrored image)
a := $FF;
Inc(pb, 1); b := byte(pb^);
Inc(pb, 1); g := byte(pb^);
Inc(pb, 1); r := byte(pb^);
p[idx] := (a SHL 24) OR (r SHL 16) OR (g SHL Cool OR (b);
end;

// Logitech gives a mirrored image, must flip.
// TODO: change for loop to read mirrored bytes.
G32.Bitmap.FlipVert(G32.Bitmap);
finally
Image.Canvas.Unlock;
G32.EndUpdate;
G32.Bitmap.Changed;
G32.Bitmap.Unlock;
end;
end;
end;
Back to top
Whome
Guest





PostPosted: Sun Jan 21, 2007 10:29 pm    Post subject: Re: Copy pBytes:Pointer rgb to Graphics32 canvas, fastest wa Reply with quote



Ok, I at least managed to read mirrored pixels directly to top-left ARGB
image format and don't have to flipVert or flipHorz at the end.

I think I go with this method, it works anyway.

procedure TForm1.SampleGrabberBuffer(sender: TObject; SampleTime: Double;
pBuffer: Pointer; BufferLen: Integer);
var
row, col: Integer;
idx: Integer;
a, r, g, b: Byte;
pb: PByte;
P: PColor32Array;
begin
if CallBack.Checked then begin
prevBufferLen := BufferLen;
prevSampleTime := SampleTime;

Image.Canvas.Lock; // to avoid flickering
G32.Bitmap.Lock;
G32.BeginUpdate;
try
// 1: Use Delphi Image
SampleGrabber.GetBitmap(Image.Picture.Bitmap, pBuffer, BufferLen);

// 2: Use Graphics32 Image
// Logitech webcam RGB24 352x288, 24 bits = 304128 bufferlen
// NOTE: source byte format may change depending on camera
// or "Play File..." file codec being used.
// For now hardcode this format.

P := G32.Bitmap.Bits;

// read mirrored pixels and copy to top-left ARGB canvas format
pb := PByte(pBuffer);
Inc(pb, BufferLen);
for row := 0 to G32.Bitmap.Height - 1 do begin
for col := 0 to G32.Bitmap.Width - 1 do begin
a := $FF;
Dec(pb, 1); r := byte(pb^);
Dec(pb, 1); b := byte(pb^);
Dec(pb, 1); g := byte(pb^);
p[G32.Bitmap.Width-1-col + (row * G32.Bitmap.Width)] :=
(a SHL 24) OR (r SHL 16) OR (g SHL Cool OR (b);
end;
end;

// draw transparent rectangle and frame timestamp
G32.Bitmap.FillRectT(0, 10, 200, 40, $8000FF00);
G32.Bitmap.Font.Size := 16;
//G32.Bitmap.Textout(10, 10, 'Time: ' + FloatToStr(sampleTime));
G32.Bitmap.RenderText(10, 10,
'Time: ' + FloatToStr(sampleTime), 4, $FF000000);

finally
Image.Canvas.Unlock;
G32.EndUpdate;
G32.Bitmap.Changed;
G32.Bitmap.Unlock;
end;
end;
end;


Whome wrote:
Quote:
http://koti.mbnet.fi/akini/delphi/dspack/
file: SampleGrabber.zip

I have edited DSPACK samplegrabber demo to use device capture and
Graphics32 image canvas.

I am not sure about how to use "pBuffer: Pointer" variable most
effective way. See example, now I increment pointer one byte when
traveling through a image size.

Is there a way to cast pBuffer to byte array, without copying a data.
This should create no extra copying 'cause callback method is called
25-50 times per seconds.

What I do here is reading RGB 24-bit pixels and convert to ARGB 32-bit
pixels.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Multimedia All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.