Problem displaying the graphics

Discussions on GFL SDK, the graphic library for reading and writing graphic files

Moderators: XnTriq, helmut, xnview

pepak
Posts: 6
Joined: Wed Dec 13, 2006 3:37 pm

Problem displaying the graphics

Post by pepak »

I am using LibGFL versions 2.66 and 2.67 to load bitmaps into a Delphi application and I am encountering problems I just can't solve. I assume it is something trivial but I just can't find out what it is. I am using three different drawing methods and all three have some problems:

A) Drawing through TBitmap object

The idea is to load a GFL bitmap and convert it into a TBitmap which is then drawn through TCanvas.Draw methods. This solution actually works, but I am rather unhappy with it as it uses a lot of memory and I rather suspect it to be quite slow.

B) Drawing through DIBs

Same as before, I load a GFL bitmap and then convert it (using gflConvertBitmapIntoDib) to a DIB. The DIB is then drawn using this code:

Code: Select all

procedure TXnBitmap.Draw(ACanvas: TCanvas; const Rect: TRect);
var Left, Top: integer;
    PDib: ^BITMAPINFO;
begin
    Left := Rect.Left;
    Top := Rect.Top;
    Width := Rect.Right - Rect.Left;
    Height := Rect.Bottom - Rect.Top;
    PDib := GlobalLock(Dib);
    try
      SetDIBitsToDevice(ACanvas.Handle, Left, Top, Width, Height, 0, 0, 0, Height, @PDib^.bmiColors[0], PDib^, DIB_RGB_COLORS);
    finally
      GlobalUnlock(Dib);
      end;
end;
Now this code also works somewhat - that is, it actually displays an image. But there are two serious but's:

1. Unless I set ColorModel to GFL_BGRA, the colors are all off (offhand, I would say that red and blue are switched). Curiously, it's not necessary to set GFL_LOAD_FORCE_COLOR_MODEL flag, just setting the ColorModel is enough to correct the problem.

2) The picture is drawn upside down. I suspect it has something to do with the fact that DIBs with Height>0 are bottom-up bitmaps, but I just can't find how to display such a bitmap in a correct direction - either I end up with an upside down picture (using the code above) or with no picture at all.

C) Drawing through DDBs

This would be my prefered method because it should be the fastest. Unfortunatelly, I just can't get any picture out of it. I load a GFL bitmap and convert it to DDB (gflConvertBitmapIntoDdb), but that's about it. The DDB seems to be correct (judging by the memory representation), but I just don't get any picture:

Code: Select all

procedure TXnBitmap.Draw(ACanvas: TCanvas; const Rect: TRect);
var Left, Top: integer;
    BmpDC: HDC;
    OldObj: HGDIOBJ;  
begin
    Left := Rect.Left;
    Top := Rect.Top;
    Width := Rect.Right - Rect.Left;
    Height := Rect.Bottom - Rect.Top;
    BmpDC := CreateCompatibleDC(ACanvas.Handle);
    try
      OldObj := SelectObject(BmpDC, DDB);
      try
        BitBlt(ACanvas.Handle, Left, Top, Width, Height, BmpDC, 0, 0, ACanvas.CopyMode);
      finally
        SelectObject(BmpDC, OldObj);
        end;
    finally
      DeleteDC(BmpDC);
      end;
The problem apparently is in the BitBlt call - it returns an error code (zero), but a successive GetLastError also returns zero, so I have no idea just what the error is.

Any help with these problems would be appreciated. I am so close to a working TGraphic based on a LibGFL, but just can't get it to work :-(

Edit: I managed to get the DDB version to work. It turns out I have to use BeginPaint/EndPaint (I would have thought that the Draw method is already in the drawing state, but apparently not). DIB still won't work, though (even with BeginPaint, EndPaint).
User avatar
xnview
Author of XnView
Posts: 44470
Joined: Mon Oct 13, 2003 7:31 am
Location: France

Re: Problem displaying the graphics

Post by xnview »

pepak wrote: B) Drawing through DIBs

Same as before, I load a GFL bitmap and then convert it (using gflConvertBitmapIntoDib) to a DIB. The DIB is then drawn using this code:

Code: Select all

procedure TXnBitmap.Draw(ACanvas: TCanvas; const Rect: TRect);
var Left, Top: integer;
    PDib: ^BITMAPINFO;
begin
    Left := Rect.Left;
    Top := Rect.Top;
    Width := Rect.Right - Rect.Left;
    Height := Rect.Bottom - Rect.Top;
    PDib := GlobalLock(Dib);
    try
      SetDIBitsToDevice(ACanvas.Handle, Left, Top, Width, Height, 0, 0, 0, Height, @PDib^.bmiColors[0], PDib^, DIB_RGB_COLORS);
    finally
      GlobalUnlock(Dib);
      end;
end;
Now this code also works somewhat - that is, it actually displays an image. But there are two serious but's:

1. Unless I set ColorModel to GFL_BGRA, the colors are all off (offhand, I would say that red and blue are switched). Curiously, it's not necessary to set GFL_LOAD_FORCE_COLOR_MODEL flag, just setting the ColorModel is enough to correct the problem.

2) The picture is drawn upside down. I suspect it has something to do with the fact that DIBs with Height>0 are bottom-up bitmaps, but I just can't find how to display such a bitmap in a correct direction - either I end up with an upside down picture (using the code above) or with no picture at all.
When you don't use gflLoadBitmapAsDIB??
Pierre.
pepak
Posts: 6
Joined: Wed Dec 13, 2006 3:37 pm

Re: Problem displaying the graphics

Post by pepak »

xnview wrote: When you don't use gflLoadBitmapAsDIB??
Because I want to use several GFL functions with the loaded bitmap, e.g. gflResize.
pepak
Posts: 6
Joined: Wed Dec 13, 2006 3:37 pm

Post by pepak »

Beides, unless I am sadly mistaken, LibGFL only supportes loading GFL_BITMAPs from a handle, other bitmap types are only supported when read from files.
MaierMan
Posts: 78
Joined: Wed Aug 04, 2004 8:32 pm

Post by MaierMan »

Where Exactly do you create the DDB?

(btw: try...finally is pretty useless when using BltBlt as Windows does not throw exceptions at you)

Using similar code myself, with BCB (which shares the VCL ;)), and it works fine...