• Welcome to Vampyre Imaging Library Forum. Please login or sign up.
 

Indexed PNG & Transparency

Started by leledumbo, 21 January 2008, 09:42:52

Previous topic - Next topic

leledumbo

21 January 2008, 09:42:52 Last Edit: 21 January 2008, 09:44:56 by leledumbo
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.

Galfar

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).

leledumbo

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?

Galfar

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).

leledumbo

So, what is the best solution for this 60 fps graphics? Is there any better function/method?

Galfar

You can try SDL, OpenGL, DirectX, or other APIs designed for fast graphics display.

leledumbo

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.

Galfar

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.

leledumbo

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.

Galfar

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.

marty

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 )

Galfar

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.

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Name:
Email:

Shortcuts: ALT+S save/post or ALT+P preview

SMF spam blocked by CleanTalk