Vampyre Imaging Library Forum

Imaging Category => Help & Questions => Topic started by: leledumbo on 21 January 2008, 09:42:52

Title: Indexed PNG & Transparency
Post by: leledumbo on 21 January 2008, 09:42:52
I'm using Imaging 0.24.2 on Lazarus 0.9.25/FPC 2.2.0.

I try to load an indexed PNG image using TSingleImage, then display it using DisplayImage function. But the result is far from expected, I only see a box with some pixels in it but it's definitely not the correct image. When I convert it to RGBA, it loads fine. From the documentation, I see that Imaging supports loading of indexed PNG. So, could this be a bug?

Another thing, after converting to RGBA, DisplayImage displays the image with transparent pixel being white. From the documentation, DisplayImage only supports ifR8G8B8A8 and ifX8G8B8A8 format. Therefore, RGBA should be displayed correctly. Any solution to this?

Thanks.
Title: Re: Indexed PNG & Transparency
Post by: Galfar on 23 January 2008, 19:17:16
If you suspect that some image is not loaded correctly try saving it back to some file (try more  file formats) right after loading and check this file. Loading could be fine but the displaying could not.

As you wrote in your post DisplayImage only supports 32bit images so it can't display 8bit indexed PNG correctly. DisplayImages uses StretchDIBits WinAPI function which assumes scanlines aligned to 32bits - so every 32bit image is fine but for example 8bit images would have to have width that is multiple of four (to get 4x8=32bit alignment). In Linux different API si used but the requirements for the image are pretty much the same.

StretchDIBits doesn't support alpha blending so no transparency can be displayed.
Rather convert image to native representation of display API you are using (ConvertImageToBitmap to get TBitmap, or SDL/D3D/OGL units).
Title: Re: Indexed PNG & Transparency
Post by: leledumbo on 24 January 2008, 08:02:29
But it's stated in the docs that converting it to TBitmap first will make the code slower, while I need it to change frequently (via Timer, with interval 1000 div 60, I expect 60 fps). Is there any other approach? Btw, can TImagingCanvas help? It's not interchangable with TCanvas, so I can't assign it to Form's Canvas property. What's this designed for?
Title: Re: Indexed PNG & Transparency
Post by: Galfar on 25 January 2008, 00:18:14
TImagingCanvas provides some drawing operations that work on images (TImageData, TSingleImage, ...). It's in no way compatible with VCL TCanvas class.

Creating new TBitmap every frame would be slow but you can create it just once and update
its bits when needed (see SetDIBits WinAPI function) - that would be much faster.
But still, using Windows GDI is not very well suited for 60fps graphics (if it's something more complex than just a few small images).
Title: Re: Indexed PNG & Transparency
Post by: leledumbo on 25 January 2008, 09:38:22
So, what is the best solution for this 60 fps graphics? Is there any better function/method?
Title: Re: Indexed PNG & Transparency
Post by: Galfar on 27 January 2008, 15:01:23
You can try SDL, OpenGL, DirectX, or other APIs designed for fast graphics display.
Title: Re: Indexed PNG & Transparency
Post by: leledumbo on 28 January 2008, 07:34:00
Hey, I've tried your suggestion about TBitmap (create it when the form is created, free when the form is destroyed). I don't see any flickering, and the fps shown is near expectation (50). The only problem now is about the indexed PNG, using the same method (convert it to TBitmap first) nothing appears on the form. I don't use DisplayImage anymore, instead I use Canvas.Draw.
Title: Re: Indexed PNG & Transparency
Post by: Galfar on 29 January 2008, 15:30:48
Try to save TBitmap created from indexed PNG to file and see if it is ok.
If it is ok than the error is in the display part, otherwise it is in the Imaging's loading code.
Maybe also attach your source indexed PNG here so I can have a look how it is handled
by Imaging.

In what pixel format is your TBitmap? If you convert indexed PNG directly to TBitmap you get
8bit TBitmap.
Title: Re: Indexed PNG & Transparency
Post by: leledumbo on 13 February 2008, 07:22:04
Hey, I just noticed that LCLImager demo can do it well. It assigns the graphic property to TImage, and the indexed image is displayed correctly. Hmm... I wonder how.
Title: Re: Indexed PNG & Transparency
Post by: Galfar on 18 February 2008, 22:24:27
Sorry, I overlooked that you are using Lazarus: no 8bit here, all LCL TBitmaps created by ConvertDataToBitmap are 32bit so they work with LCL TImage (as you noticed with LCLImager).
DisplayImage should work for those too. If it doesn't upload you image here as an attachment.
Title: Re: Indexed PNG & Transparency
Post by: marty on 23 June 2008, 13:28:59
hi there

this is my first day on vampyre library, and so be good with me, i'm just trying for now lol

there is my code:



procedure TForm1.BitBtn2Click(Sender: TObject);
var
  ImgClass: TBaseImage;
  AString1,AString2:string;
begin
  AString1:='/home/marty/inworker/lazarus0922/testvampyre/brown/image1.png';
  AString2:='/home/marty/inworker/lazarus0922/testvampyre/brown/image1_x.png';
  imgClass := TSingleImage.Create;
  imgClass.Format := ifA8R8G8B8;
  imgClass.LoadFromFile(AString1);
  imgClass.SaveToFile(AString2);
  DisplayImage(Image1.Canvas,0,0,ImgClass);
end;


this is a transparent png
the load is correct, because when i look on image1_x.png, the transparency is kept.
But the display is not correct, the background is black.
Could you tell me what i've done bad ?
thanks for your help
( ubuntu 8.04, lazarus 0.9.24, vampyre last on the site )
Title: Re: Indexed PNG & Transparency
Post by: Galfar on 8 July 2008, 11:27:19
Quote from: marty on 23 June 2008, 13:28:59
hi there
this is my first day on vampyre library, and so be good with me, i'm just trying for now lol

this is a transparent png
the load is correct, because when i look on image1_x.png, the transparency is kept.
But the display is not correct, the background is black.
( ubuntu 8.04, lazarus 0.9.24, vampyre last on the site )


DisplayImage uses GTK function gdk_draw_rgb_32_image to draw image in Lazarus apps built with LCL/GTK so the problem most probably lies here (does it support alpha blending at all?).
DisplayImage is more of a image preview function using native OS APIs to draw to app windows.
Try converting the image to TBitmap and draw it - drawing will be done by LCL and maybe it
handles transparent bitmaps well (it does in Windows since Laz 0.9.24).

Just to check upload your testing image here please.

Also setting imgClass.Format := ifA8R8G8B8; before loading from file is pointless,
image will always have format based on the loaded image.
If you want to make sure the image is in specific format, convert it after
the loading.