Forum > Graphics

Imported raw bitmap displays mirrored (upside-down)

(1/2) > >>

Hitnrun:
Hello!

I am trying to port an application from windows, where I have a pointer to bitmap data in BGR24 format (default windows DIB).

In windows I do:


--- Code: ---
procedure display(pData: Pointer);
var
  b: TBitmap;
  bi: TBitmapInfo;
begin
     FillChar(bi, sizeof(bi), 0);

     bi.bmiHeader.biWidth := FWindowWidth;
     bi.bmiHeader.biHeight := -FWindowHeight;

     bi.bmiHeader.biPlanes := 1;
     bi.bmiHeader.biBitCount := 24;
     bi.bmiHeader.biSizeImage := 0;
     bi.bmiHeader.biSize := sizeof(TBitmapInfoHeader);
     bi.bmiHeader.biClrUsed := 0;
     bi.bmiHeader.biClrImportant := 0;

     b := TBitmap.Create;

     b.Height := 0;
     b.Width := FWindowWidth;
     b.Height := FWindowHeight;

     if SetDIBits(b.Canvas.Handle, b.Handle, 0, FWindowHeight, pData, bi, DIB_RGB_COLORS) = 0 then raise Exception.Create('error');


      FWindow.Canvas.StretchDraw(Rect(0, 0, FDisplayWidth, FDisplayHeight), b);

      b.Free;
end;

--- End code ---


Note that on windows, I pass the parameter

     bi.bmiHeader.biHeight := -FWindowHeight;

as negative, so the SetDIBits function displays the image right. If I leave it positive, the image displays mirrored just like I am getting with lazarus.

On lazarus, my code looks like:


--- Code: ---
procedure display(pData: Pointer);
var
  B: HBITMAP;
  bmp: TBitmap;
begin
     bmp := TBitmap.Create;

     B := CreateBitmap(FWindowWidth, FWindowHeight, 1, 24, pData);
     if B = 0 then
        raise Exception('Error creating bitmap');
     
     bmp.CreateFromBitmapHandles(B, 0, Rect(0, 0, FWindowWidth, FWindowHeight));

        FWindow.Canvas.StretchDraw(Rect(0, 0, FDisplayWidth, FDisplayHeight), FOffscreen);
     
     DeleteObject(B);

   bmp.Free;
end;

--- End code ---


but the image displays mirrored.

Is there an equivallent parameter of the negative parameter of SetDIBits? What is wrong, my image was inverted, or the CreateBitmap inverts it?

Thanks!

Marc:
windows bitmaps are stored in a reversed order. So when crating one you need to pass the image lines in a reversed order.
For DIBs you can indeed tell windows that the ordering is from top to bottom.

Hitnrun:

--- Quote from: "Marc" ---windows bitmaps are stored in a reversed order. So when crating one you need to pass the image lines in a reversed order.
For DIBs you can indeed tell windows that the ordering is from top to bottom.
--- End quote ---


Ok, in Windows I pass the height as a negative value, so how I do this in Lazarus/FPC? I tried passing the height as negative in various funcions, all of them gave errors...

Marc:
what functions did you use ?

The easiest way to load raw image data into a bitmap is using TRawImage. There you can setup a description which matches exactly your data.

Hitnrun:
The ones I posted on the first post!  :wink:


--- Code: ---
procedure display(pData: Pointer);
var
  B: HBITMAP;
  bmp: TBitmap;
begin
     bmp := TBitmap.Create;

     B := CreateBitmap(FWindowWidth, FWindowHeight, 1, 24, pData);
     if B = 0 then
        raise Exception('Error creating bitmap');
     
     bmp.CreateFromBitmapHandles(B, 0, Rect(0, 0, FWindowWidth, FWindowHeight));

        FWindow.Canvas.StretchDraw(Rect(0, 0, FDisplayWidth, FDisplayHeight), FOffscreen);
     
     DeleteObject(B);

   bmp.Free;
end;

--- End code ---


pData is a pointer to image bytes, the width, height and depth I know from previous funcions calls.

Navigation

[0] Message Index

[#] Next page

Go to full version