the following uses gdi+ (SFSxOI's gdi+ wrappers and Freak's macro framework are required) to save a 'regular' 32-bit bitmap (which may have alpha transparency defined) in png format whilst preserving the alpha transparency. Of course Purebasic's SaveImage() command does not preserve the alpha channel when saving to png format.
The function presented here does have to scan each pixel in the source image and so will not be the fastest method in the world. However, I think the only way to speed this up would be to use gdi+ to create the original bitmap in the first place, which kind of defeats the object of this code!

Being new to gdi+ I will however try and find a quicker method.
AlphaBmp2Png.pbi
Code: Select all
;'AlphaBmp2Png'.
;-----------------
; srod + Netmaestro.
; Created with Purebasic 4.1 for Windows.
;
; Date: August 2007.
;
; Platforms: Windows.
; The gdi+ library needs to be installed which comes as standard with XP.
; Earlier versions of Windows require the gdi+ redistributable.
;
; Requirements : The Purebasic gdi+ wrappers found here :
; http://www.purebasic.fr/english/viewtopic.php?t=26459
; and the macro framework which is linked to in the above thread.
;
; Licence: DAYLike
; (Do As You Like with it! - No Warranties!)
; A credit to myself, whilst nice, is not absolutely necessary.
;
;*******************************************************************************************
;
;NOTES.
;------
;The function AlphaBmp2Png() will take a 32-bit gdi bitmap (such as those created by
;CreateImage() etc.) whose pixel data may or may not record alpha transparency and save
;it in the form of a png image file.
;Unlike PB's SaveImage() command, however, AlphaBmp2Png() will also save the alpha channel data.
;
;*******************************************************************************************
XIncludeFile "gdiplus_11.pbi" ;See the requirements listed above.
;Returns zero if an error, non-zero otherwise.
Procedure.l AlphaBmp2Png(hBmp, filename$)
Protected result, bmp.BITMAP, gdiplusimage, i, j
Protected *px.LONG
If LCase(GetExtensionPart(filename$)) = "png"
If GetObject_(hBmp, SizeOf(BITMAP), bmp.BITMAP) And bmp\bmBitsPixel = 32
;Initialise gdi+.
gdiToken = Gdiplus_New()
If gdiToken
;Let's create our gdi+ bitmap.
If GdipCreateBitmapFromScan0(bmp\bmWidth, bmp\bmHeight, 0, #PixelFormat32bppARGB, 0, @gdiplusimage) = #Ok
;Scan each pixel of the original image and copy the colour and alpha settings.
For i=0 To bmp\bmHeight-1
For j=0 To bmp\bmWidthBytes-1 Step 4
*px = bmp\bmBits + bmp\bmWidthBytes * i + j
SetPixel(gdiplusimage, j/4, i, *px\l)
Next
Next
;Save as png.
If Gdiplus_ImageSaveToFile(gdiplusimage, filename$, #Png_Encoder) = #Ok
result=1
EndIf
;Tidy up.
GdipDisposeImage(gdiplusimage)
EndIf
Gdiplus_Del(gdiToken)
EndIf
EndIf
EndIf
ProcedureReturn result
EndProcedure