Jump to content

[GDI+] Why doesnt this save transparent png? [Solved]


PAEz
 Share

Recommended Posts

#include <WinAPI.au3>
#include <GDIPlus.au3>
_GDIPlus_Startup()
Local $width=100, $height=100, $ch_image, $ch_graphic, $ch_bitmap
 
$ch_bitmap = _WinAPI_CreateBitmap( $width , $height , 1 , 32 )
;$ch_image = _GDIPlus_ImageLoadFromFile (@MyDocumentsDir & "\123.png")
$ch_image = _GDIPlus_BitmapCreateFromHBITMAP($ch_bitmap)
$ch_graphic = _GDIPlus_ImageGetGraphicsContext($ch_image)
_GDIPlus_GraphicsClear($ch_graphic, 0x00FFFFFF)
_GDIPlus_ImageSaveToFile($ch_image, @MyDocumentsDir & "\11111.png")
_GDIPlus_Shutdown()

As the title asks, why doesnt this save a transparent png?

If I set the image by loading a png with transparency then it does as expected, but if I use CreateBitmap then it saves a black picture.

Im on XP incase that makes a difference.

Edited by PAEz
Link to comment
Share on other sites

I don´t know why happend that.. i will do something like this

#include <GDIPlus.au3>
#include <Constants.au3>
Global Const $STM_SETIMAGE = 0x172

_CreateClearPNG(@DesktopDir & "\MyPNG.png", 0x55FF0000)

Func _CreateClearPNG($sFile, $iColor)
    _GDIPlus_Startup()
    Local $hImage = _GDIPlus_BitmapCreateFromScan0(100, 100)
    Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)
    _GDIPlus_GraphicsClear($hGraphics, "0x" & Hex($iColor, 8))
    _GDIPlus_ImageSaveToFile($hImage, $sFile)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_BitmapDispose($hImage)
    _GDIPlus_Shutdown()
EndFunc   ;==>_CreateClearPNG
Func _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $iStride = 0, $iPixelFormat = 0x0026200A, $pScan0 = 0)
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iStride, "int", $iPixelFormat, "ptr", $pScan0, "int*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[6]
EndFunc   ;==>_GDIPlus_BitmapCreateFromScan0

EDITED

Edited by monoscout999
Link to comment
Share on other sites

Hi,

Use _GDIPlus_BitmapLockBits() to play with the pixels.

This code will actually generate a blank transparent png in xp , or at least it does for me :mellow:

#include <WinAPI.au3>
#include <GDIPlus.au3>

Global $iW = 100, $iH = 100, $hBitmap, $hBMP, $tBitmapData, $tPixels

_GDIPlus_Startup()
$hBitmap = _WinAPI_CreateBitmap($iW, $iH , 1 , 32)
$hBMP = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_WinAPI_DeleteObject($hBitmap)
$hBitmap = _GDIPlus_BitmapCloneArea($hBMP, 0, 0, $iW, $iH, $GDIP_PXF32ARGB)
_GDIPlus_BitmapDispose($hBMP)
$tBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32ARGB)
$tPixels = DllStructCreate("byte[" & $iH * $iW * 4 & "]", DllStructGetData($tBitmapData, "Scan0")) ; Create DLL structure for all pixels
DllStructSetData($tPixels, 1, StringReplace(DllStructGetData($tPixels, 1), "000000FF", "00000000"))
_GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData)
$tPixels = 0
$tBitmapData = 0
_GDIPlus_ImageSaveToFile($hBitmap, @MyDocumentsDir & "\11111.png")
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()

Cheers

Link to comment
Share on other sites

Oh Thank You Both SOOOOO Much!.....that was driving me nuts ;P

As to why it happens I think its because when you define it as having 32bits it thinks you mean 32bits without alpha...I had a look at the msdn (think thats what its called) and they mentioned that theres a 32bit without alpha, seems silly to me.

_GDIPlus_BitmapCreateFromScan0

....should be added to the UDF, very clean solution.

One thing, why do you convert the color in GraphicsClear to a string?...using a number like 0x00FFFFFF worked fine.

And thanks for the tip on LockBits I had been looking at that. Saw some routines on the forum that use that to change the alpha of a bitmap and Im going to need that later and I like to know how things work.

Link to comment
Share on other sites

One thing, why do you convert the color in GraphicsClear to a string?...using a number like 0x00FFFFFF worked fine.

my mistake.. i didn`t try that simple way, because when i pass the string like this 0x55ff0000 whitout the quotes "" in the function is transformed to a integer
Link to comment
Share on other sites

Hows that?

I changed

DllStructSetData($tPixels, 1,StringReplace(DllStructGetData($tPixels,1),"000000FF","00000000"))

to

DllStructSetData($tPixels, 1,StringReplace(DllStructGetData($tPixels,1),"000000FF","00000088"))

and got what I would expect an image that was semitransparent...loaded it in Paint.Net and it seemed fine.

Prefer the first way tho, nice and clean.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...