Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

function cvImage2Bitmap() didn't work, i wrote a new one #134

Open
OllinuxD opened this issue May 29, 2020 · 6 comments
Open

function cvImage2Bitmap() didn't work, i wrote a new one #134

OllinuxD opened this issue May 29, 2020 · 6 comments

Comments

@OllinuxD
Copy link

function cvImage2Bitmap didn't work for me, it produced an exception.

this code instead works:

function cvImage2Bitmap(img: PIplImage): {$IFDEF DELPHIXE2_UP}Vcl.Graphics.TBitmap{$ELSE}Graphics.TBitmap{$ENDIF}; var bmp: {$IFDEF DELPHIXE2_UP}Vcl.Graphics.TBitmap{$ELSE}Graphics.TBitmap{$ENDIF}; deep: Integer; y, x, c, wStep, Channels: Integer; srcPtr: PByte; destPtr: PByte; wAdd: Integer; begin Result := nil; if (img <> nil) then begin bmp := {$IFDEF DELPHIXE2_UP}Vcl.Graphics.TBitmap.Create{$ELSE}Graphics.TBitmap.Create{$ENDIF}; bmp.SetSize(img^.Width, img^.Height); deep := img^.nChannels * img^.depth; case deep of 8: bmp.PixelFormat := pf8bit; 16: bmp.PixelFormat := pf16bit; 24: bmp.PixelFormat := pf24bit; 32: bmp.PixelFormat := pf32bit; end; wStep := img^.WidthStep; Channels := img^.nChannels; srcPtr := Pointer(img^.ImageData); wAdd := wStep - (img^.width * Channels); for y := 0 to img^.Height - 1 do begin destPtr := bmp.Scanline[y]; for x := 0 to img^.Width - 1 do begin for c := 0 to Channels - 1 do begin destPtr^ := srcPtr^; Inc(destPtr); Inc(srcPtr); end; end; srcPtr := Pointer(NativeUint(srcPtr) + NativeUInt(wAdd)); end; Result := bmp; end; end;

@Laex
Copy link
Owner

Laex commented Mar 12, 2021

How can I reproduce the error?
Which version of Delphi?
More details ...

@OllinuxD
Copy link
Author

OllinuxD commented Mar 12, 2021 via email

@HuguesDug
Copy link

HuguesDug commented May 7, 2022

Same on my side.

Sample of code that create the error :
Don't get confused with the TMemoryStream. I use in FMX and not VCL. The two verion of bitmap are not directly compatible.

type
TVclBitmap = Vcl.Graphics.TBitmap;
var
AVCLbitmap: TVclBitmap;
AStream: TMemoryStream;
Frame:PIplImage;
begin
if Capture <> nil then
begin
image := cvQueryFrame(Capture);
if image <> nil then
begin
Frame:=cvCloneImage(image);
AStream := TMemoryStream.Create;
try
AVCLbitmap := cvImage2Bitmap(Frame);
AVCLbitmap.SaveToStream(AStream);
AStream.Position := 0;
CameraInput.Bitmap.LoadFromStream(AStream);
finally
AStream.free;
AVCLbitmap.free;
CvReleaseImage(Frame);
end;
end;
end;
end;

Environnement : Delphi 10.4.2, windows 32 plateform.

It seams it has to see with the line
pb[3 * j + K] := data[i * wStep + j * Channels + K]

I commented out, no more error... but of course, no more image translation.

@HuguesDug
Copy link

function cvImage2Bitmap didn't work for me, it produced an exception.

this code instead works:

function cvImage2Bitmap(img: PIplImage): {$IFDEF DELPHIXE2_UP}Vcl.Graphics.TBitmap{$ELSE}Graphics.TBitmap{$ENDIF}; var bmp: {$IFDEF DELPHIXE2_UP}Vcl.Graphics.TBitmap{$ELSE}Graphics.TBitmap{$ENDIF}; deep: Integer; y, x, c, wStep, Channels: Integer; srcPtr: PByte; destPtr: PByte; wAdd: Integer; begin Result := nil; if (img <> nil) then begin bmp := {$IFDEF DELPHIXE2_UP}Vcl.Graphics.TBitmap.Create{$ELSE}Graphics.TBitmap.Create{$ENDIF}; bmp.SetSize(img^.Width, img^.Height); deep := img^.nChannels * img^.depth; case deep of 8: bmp.PixelFormat := pf8bit; 16: bmp.PixelFormat := pf16bit; 24: bmp.PixelFormat := pf24bit; 32: bmp.PixelFormat := pf32bit; end; wStep := img^.WidthStep; Channels := img^.nChannels; srcPtr := Pointer(img^.ImageData); wAdd := wStep - (img^.width * Channels); for y := 0 to img^.Height - 1 do begin destPtr := bmp.Scanline[y]; for x := 0 to img^.Width - 1 do begin for c := 0 to Channels - 1 do begin destPtr^ := srcPtr^; Inc(destPtr); Inc(srcPtr); end; end; srcPtr := Pointer(NativeUint(srcPtr) + NativeUInt(wAdd)); end; Result := bmp; end; end;

Works for me... except I have to remove the IfDef and else, as the ifdef clause is not recognized by 10.4... for a reason I don't know.

@sun5152
Copy link

sun5152 commented Jan 3, 2024

Array out range

PByteArray = ^TByteArray;
TByteArray = array[0..32767] of Byte;

function cvImage2Bitmap(img: PIplImage): {$IFDEF DELPHIXE2_UP}Vcl.Graphics.TBitmap{$ELSE}Graphics.TBitmap{$ENDIF};
var
// info: string;
bmp: {$IFDEF DELPHIXE2_UP}Vcl.Graphics.TBitmap{$ELSE}Graphics.TBitmap{$ENDIF};
deep: Integer;
i, j, K, wStep, Channels: Integer;
// data: PByteArray;
// pb: PByteArray;
pb,pData: Pointer;
offset:longint;
begin
Result := NIL;
if (img <> NIL) then
begin
bmp := {$IFDEF DELPHIXE2_UP}Vcl.Graphics.TBitmap.Create{$ELSE}Graphics.TBitmap.Create{$ENDIF};
bmp.Width := img^.Width;
bmp.Height := img^.Height;
deep := img^.nChannels * img^.depth;
case deep of
8:
bmp.PixelFormat := pf8bit;
16:
bmp.PixelFormat := pf16bit;
24:
bmp.PixelFormat := pf24bit;
32:
bmp.PixelFormat := pf32bit;
End;

wStep := img^.WidthStep;
Channels := img^.nChannels;

// data := Pointer(img^.ImageData);

for i := 0 to img^.Height - 1 do
begin
  pb := bmp.Scanline[i];
  offset := longint(img^.ImageData) + wStep * i;
  pData := Pointer(offset);
  copymemory(pb, pData, wStep);

// for j := 0 to img^.Width - 1 do
// begin
// for K := 0 to Channels - 1 do
// pb[Channels * j + K] := data[i * wStep + j * Channels + K];
// End;
End;
Result := bmp;
// bmp.Free;
End;
end;

@OllinuxD
Copy link
Author

OllinuxD commented Jan 3, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants