How do I load a PNG file with alpha channel?

BlitzMax Forums/BlitzMax Beginners Area/How do I load a PNG file with alpha channel?

Rozek(Posted 2007) [#1]
Hello!

I would like to load a PNG file which contains alpha channel information in order to use it, e.g., as a pixmap in "setPanelPixmap" - and the solution should be cross-platform.

Thanks in advance for any ideas!


FlameDuck(Posted 2007) [#2]
Local whatever:TPixmap = LoadPixmap("myImage.png")

However, alphachannel information is fairly useless as a PanelPixmap, as the Panel is opaque.


Rozek(Posted 2007) [#3]
Well,

"loadPixmap" was my initial choice - but, unfortunately, the transparent regions (of the PNG image) are rendered black rather than in the panel's background color.

That's also what I need transparent images for: they contain pictures with irregular shape and I want the panel's background color to shine through - the panel itself may be opaque, that does not matter.


Brucey(Posted 2007) [#4]
I don't believe the Win32 panels support transparent images?
(but I could be wrong)

I know that Mac and Linux (GTK) do.

As the Duck says, should be a simple case of loading the Pixmap and setting the panel with it. If it doesn't work......


Rozek(Posted 2007) [#5]
Brucey,

Win32 panels support transparent GIFs, at least, that's why I'm surprised, that transparent PNGs don't work under Win32. I had no success using transparent GIFs or PNGs under MacOSX and Linux yet


Brucey(Posted 2007) [#6]
I had no success using transparent GIFs or PNGs under MacOSX and Linux yet

You haven't tried or you have and it didn't work?

Cuz I have tests (that go with my module developments) that show it working on Linux (GTK).
I also have seen it working on Mac, though I haven't played with them on Mac for a while.


Rozek(Posted 2007) [#7]
Brucey,

well, I tried...and it didn't work. Being a BlitzMax newbie, however, I did not know whether it's *my* problem or BlitzMax'

Is there a special approach? Will I have to "import" a special module (in addition to "BRL.PNGloader")? Will I have to use "loadPixmapPNG" rather than "loadPixmap"? Under Linux: will I need special versions of special libraries (I know that Linux is often very nitpicking about certain libs)


Rozek(Posted 2007) [#8]
Well,

please find below screen shots of my various tests under WinXP, MacOSX and Linux - always using the latest BlitzMax with synchronized modules.

The GIF and PNG versions of the BlitzMax-Logo are shown below:

(GIF version)
(PNG version)

WinXP-Screenshot:



(don't let yourself be misleaded by the "transparent" appearance of the .bmp image - the background color has just been chosen properly in order to produce that effect. What's more important: obviously, PNG alpha channel does not work)

MacOSX-Screenshot:


(not bad - although the ".bmp" breaks as soon as you force a repaint. Additionally, the "dividers" do not appear which is rather bad)

Linux-Screenshot:



(how poor, nothing works, neither .bmp display nor PNG transparency)

And here is the source code of my little program:



Hmmm, as you can see, I got the PNG transparency working under MacOSX only - and the GIF never shows up - meanwhile, I also tried several GIF files (without success) because my first impression was that my GIF file could be broken.


Rozek(Posted 2007) [#9]
Just FYI (should you be curious)

The program has been designed using LogicGUI - after source creation, I added the import statements, modified the "loadPixmap" calls (especially the Windows-sepcific file paths!) and modified the event handling section.

This is why the code might look somewhat "strange" - but that shold *not* affect its behavour!


Rozek(Posted 2007) [#10]
Additional information from my experiments:

- "dividers" appear under MacOSX, as soon as I "createPanel" without any border request
- sometimes, .bmp images appear properly under Linux (and I'm always talking about the same .bmp file!)

Thus, the most important question which remains is: how do I get transparent PNG images under Win32 and Linux?


Scienthsine(Posted 2007) [#11]
I just started learning OpenGL in BMax today, and I'm having this problem. I'm loading my images with LoadPixmap() before shipping htem to the graphics card for a texture, and it seems that LoadPixmap() discards .png alpha. It loads it with the format PF_RGBA8888, but all of the alpha data is set to full. I used MaskPixmap() to create another pixmap with an alpha determined by a mask color. This shows up like it should, so my OpenGL part of everything is correct.

Anyway, was this issue ever resolved?


Brucey(Posted 2007) [#12]
Scienthsine, this is a different issue altogether, you probably need to call :

SetBlend ALPHABLEND


Dreamora(Posted 2007) [#13]
thats actually not fully true

Windows uses ugly pink (255,0,255 when i remember correcty) on the image for transparent (masking) on panel pixmaps ...


Scienthsine(Posted 2007) [#14]
Brucey> Actually I'm not using Max2D for drawing. I am using the png loader with pixmaps, however. I've tested with both an alpha test via glAlphaFunc(GL_LESS,.5) glEnable(GL_ALPHA_TEST), and with glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_BLEND). Or whatever, that's off the top of my head, and I don't have the constants and everything completley memorized, but it's correct in my code.

Anyway, alpha drawing in my code works, as I can modify the alpha values myself, and it works, I can also use 'MaskPixmap()' to create a pixmap with an alpha channel defined by a color specified, and it draws correctly.

The problem, I'm pretty sure, is that the Pixmap loader for PNG isn't setting the alpha values. I'm also pretty sure it's restricted to pixmaps, as I have used pngs with alpha channels in Max2D before with success.

Finally I believe the original poster has the same issue, as he's loading a png into a pixmap, and loosing the alpha component. People are focusing on a symptom of the problem, inthat they're not transparent in conjunction with panels.

I could be wrong, but I'm pretty certain I'm not.


Gabriel(Posted 2007) [#15]
It sounds to me as though you're using an old version of PNGLoader. Alpha support has been in for quite some time, and I know it's working fine because I rely on it for my texture packing utility. So either you're using an old version of brl.PNGLoader or you're up to date and I'm not.

Looks like I'm using 1.04 if that helps.


Scienthsine(Posted 2007) [#16]
Version 1.04
Author Mark Sibly
License Blitz Shared Source Code
Copyright Blitz Research Ltd
Modserver BRL
History 1.04
History libpng update to 1.2.12.
History Extra load error handling.
History 1.03 Release
History Added Gray/Alpha support
History 1.02 Release
History Fixed palettized/grayscale support

Hmm... I have 1.04 also, and see where they added the Alpha support...

I dunno, I'll do a more appropriate test later, time for bed. Maybe I'm missing a flag or something somewhere... or maybe gimp isn't exporting my alpha channel..... *suspicious*


Otus(Posted 2007) [#17]
Gimp alpha works for me, but I've only used it in Max2D.


Dreamora(Posted 2007) [#18]
Once again: WinAPI UI does NOT support alpha and MaxGUI does not support more than that.

Cocoa (OSX 10.3+) is the only UI beside upcomming KDE4 and Windows vista that supports TRUE ALPHA on regular UI elements

With a 2D desktop you can not use true alpha, it would make it seriously slower! (unusable if you used an alpha based theme)

So once again: Use the transparency masking color for your pixmaps.


ziggy(Posted 2007) [#19]
I think It could be done in Windows using some GDI+ API, but I'm not sure how the drawing context can be managed from within BlitzMax.


Scienthsine(Posted 2007) [#20]
Well, this simple test doesn't work for me, anyone care to tell me why? I'm not doing anything with the panels, but this would be the reason he isn't getting transparency when loading a pixmap... although it may be a problem with windows not supporting it in a panel also.

A test image:


Local image:TImage
Local pixmap:TPixmap

Graphics 800,600
SetBlend ALPHABLEND

image = LoadImage("cube.png")
pixmap = LoadPixmap("cube.png")


Repeat

	Cls
		DrawImage image,GraphicsWidth()/2-ImageWidth(image)-5,GraphicsHeight()/2-ImageWidth(image)/2
		DrawPixmap pixmap,GraphicsWidth()/2+5,GraphicsHeight()/2-PixmapHeight(pixmap)/2
	Flip
Until KeyHit(KEY_ESCAPE)



UPDATE:
Ok, my apologies, my problem is infact different.

Finally while trying everything under the sun to figure out why my code wasn't working, I found: glTexImage2D(GL_TEXTURE_2D,0,3,temp.w,temp.h,0,GL_RGBA,GL_UNSIGNED_BYTE,PixmapPixelPtr(tempPix))

Which should be: glTexImage2D(GL_TEXTURE_2D,0,4,temp.w,temp.h,0,GL_RGBA,GL_UNSIGNED_BYTE,PixmapPixelPtr(tempPix))

So even though I was sending it the correct format, the correct byte ptr, with the correct alpha values, and even setting all of my alpha drawing stuff correctly, it wasn't getting my alpha values because I sent it a pixel width of 3 bytes instead of 4 :p

Verdict: LoadPixmap() does get alpha values as it should. DrawPixmap() doesn't draw alpha, as it sets the blend mode to SOLID.
The above issue is indeed unrelated, and is probley related to the OS's in question not having true 3D gadgets, as stated above.

My mistake, thanks for the help all.