 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Whome Guest
|
Posted: Sun Jan 21, 2007 9:11 am Post subject: Copy pBytes:Pointer rgb to Graphics32 canvas, fastest way? |
|
|
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 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
|
Posted: Sun Jan 21, 2007 10:29 pm Post subject: Re: Copy pBytes:Pointer rgb to Graphics32 canvas, fastest wa |
|
|
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 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 |
|
 |
|
|
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
|
|