Jump to content
Sign in to follow this  
PAEz

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

Recommended Posts

PAEz

#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

Share this post


Link to post
Share on other sites
monoscout999

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

Share this post


Link to post
Share on other sites
smashly

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

Share this post


Link to post
Share on other sites
PAEz

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.

Share this post


Link to post
Share on other sites
monoscout999

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

Share this post


Link to post
Share on other sites
wakillon

monoscout999's solution give a real transparency effect in a photo editor but not smashly's script.


AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites
PAEz

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.

Share this post


Link to post
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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.