Sign in to follow this  
Followers 0
Malkey

Saving Image with specific color Transparency.

8 posts in this topic

My objective is to specify a color in a multi-colored image to be transparent. Then, to save that resultant image to an image file. The image file when viewed would appear to have transparent parts where the specified color used to be.

And, this process is done really fast.

Summary

I am after a fast way of saving to file, a GUI with transparent parts.

My problem and what I need help with is the transparent parts will not appear in the saved image file (a PNG image file).

I am open to all suggestions. Another method, maybe.

My attempt :-

#include <Constants.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
; http://www.autoitscript.com/forum/index.php?s=&showtopic=56481&view=findpost&p=428717
;Local Const $ULW_ALPHA = 2
Global $iTransparentColor  = 0xFFFFFFFF ;= 0xFF000000;= 0x3A6EA5;  ;  = 0xD4D0C8 ;= 0xFFB0C4DE;
Global $iWidth, $iHeight,$hBitmap,$hBitmap1,$hBitmap2,$GuiSizeX = 400, $GuiSizeY = 400
;GUISetBkColor($iTransparentColor)
$hGUI2 = GUICreate("$hGUI2", $GuiSizeX, $GuiSizeY, -1, -1, 0, ($WS_EX_LAYERED)); -1, -1, 420, 10,$WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) ;-1, $WS_EX_LAYERED)

GUISetState(@SW_SHOW)

WinSetTrans($hGUI2, "", 254)
_GDIPlus_Startup()
$hBitmap = _ScreenCapture_Capture("",0,0, $GuiSizeX, $GuiSizeY, False)
$hImage2   = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
$iWidth   = _GDIPlus_ImageGetWidth($hImage2)
$iHeight  = _GDIPlus_ImageGetHeight($hImage2)
$aWinPos = WinGetPos("$hGUI2")
WinMove("$hGUI2", "", $aWinPos[0], $aWinPos[1], $iWidth, $iHeight)
_GDIPlus_ImageDispose($hImage2)
$hDDC2 = _WinAPI_GetDC($hGUI2)
$hCDC2 = _WinAPI_CreateCompatibleDC($hDDC2)
_WinAPI_SelectObject($hCDC2,$hBitmap)
$hImage2   = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
ConsoleWrite("$hImage2 " & hex($hImage2) & @CRLF)
;$hGraphics2 = _GDIPlus_GraphicsCreateFromHDC($hCDC2)
;ConsoleWrite("$hGraphics2 " & $hGraphics2  &@CRLF)

;_GDIPlus_GraphicsDrawImage($hGraphics2, $hImage2, 0, 0)
;_WinAPI_BitBlt($hDDC2, 0, 0, $iWidth, $iHeight, $hCDC2, 0, 0, $SRCCOPY ); $SRCINVERT) ; $SRCAND); $NOTSRCCOPY); 
;GDIPlus_AlphaBlend($hDDC2, 0, 0, $iWidth, $iHeight, $hCDC2,0, 0, $iWidth, $iHeight)
if Not IsNumber($iTransparentColor) Then $iTransparentColor = "0x" & Hex(PixelGetColor(3,3,$hGUI2),6) ;GetPixel($hGUI2,3,3)
ConsoleWrite("$iTransparentColorDeclared " & Hex($iTransparentColor) &@CRLF)

_WinAPI_TransparentBlt($hDDC2, 0, 0, $iWidth, $iHeight, $hCDC2, 0, 0, ($iTransparentColor))
_API_SetLayeredWindowAttributes($hGUI2, $iTransparentColor)

#cs
$tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", $iWidth)
    DllStructSetData($tSize, "Y", $iHeight)
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", 254)    ;0xFFCC8040)Alpha
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow ($hGUI2, $hDDC2, 0, $pSize, $hCDC2, $pSource, 0, $pBlend, 2) ;$ULW_COLORKEY )
#ce
$hBitmap1 = _GDIPlus_ImageCreateGDICompatibleHBITMAP($hImage2)
ConsoleWrite("$hBitmap1 " & $hBitmap1 &@CRLF)
$hImage1   = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)
ConsoleWrite("$hImage1 " & $hImage1 &@CRLF)

$sCLSID = _GDIPlus_EncodersGetCLSID ("PNG")

;$tData = DllStructCreate("int Data")
;DllStructSetData($tData, "Data", 0)
;$tParams = _GDIPlus_ParamInit (1)
;_GDIPlus_ParamAdd ($tParams, $GDIP_EPGCOLORDEPTH , 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))

_GDIPlus_ImageSaveToFileEx ($hImage1, @DesktopDir & "\TestWrite.png",$sCLSID) ;,DllStructGetPtr($tParams))
ShellExecute(@DesktopDir & "\TestWrite.png")

;_GDIPlus_GraphicsDispose($hGraphics2)
_GDIPlus_ImageDispose($hImage1)
_GDIPlus_ImageDispose($hImage2)
;_GDIPlus_ImageDispose($hImage3)
_WinAPI_DeleteObject($hBitmap)
_WinAPI_DeleteObject ($hBitmap2)
_WinAPI_DeleteObject ($hBitmap1)
_WinAPI_ReleaseDC($hGUI2, $hDDC2)
_WinAPI_DeleteDC($hCDC2)
_GDIPlus_Shutdown()

While 1
    $nMsg = GUIGetMsg()
    sleep(20)
    
    Switch $nMsg    
        Case $GUI_EVENT_CLOSE
            FileDelete(@DesktopDir & "\TestWrite.png")
            Exit
    EndSwitch
WEnd
Exit

Func _API_SetLayeredWindowAttributes($hwnd, $i_transcolor, $Transparency = 255, $isColorRef = False)   
    Local Const $AC_SRC_ALPHA = 1
    Local Const $ULW_ALPHA = 2
    Local Const $LWA_ALPHA = 0x2
    Local Const $LWA_COLORKEY = 0x1
    If Not $isColorRef Then
        $i_transcolor = Hex(String($i_transcolor), 6)
        $i_transcolor = Execute('0x00' & StringMid($i_transcolor, 5, 2) & StringMid($i_transcolor, 3, 2) & StringMid($i_transcolor, 1, 2))
    EndIf
    Local $Ret = DllCall("user32.dll", "int", "SetLayeredWindowAttributes", _
                                      "hwnd", $hwnd, _
                                      "long", $i_transcolor, _
                                      "byte", $Transparency, _
                                      "long", BitOR($LWA_COLORKEY , $LWA_ALPHA))
    Select
        Case @error
            Return SetError(@error,0,0)
        Case $ret[0] = 0
            Return SetError(4,0,0)
        Case Else
            Return 1
    EndSelect
EndFunc   ;==>_API_SetLayeredWindowAttributes

Func _WinAPI_TransparentBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc,$iColor)
    Local $aResult
    $iColor = hex($iColor,6)
    $aResult = DllCall("GDI32.dll", "int", "GdiTransparentBlt", _
                                   "hwnd", $hDestDC, _
                                    "int", $iXDest, _
                                    "int", $iYDest, _
                                    "int", $iWidth, _
                                    "int", $iHeight, _
                                   "hwnd", $hSrcDC, _
                                    "int", $iXSrc, _
                                    "int", $iYSrc, _
                                    "int", $iWidth, _
                                    "int", $iHeight, _
                                    "int", $iColor)
    If @error Then Return SetError(@error, 0, False)
    ;$res = "GdiTransparentBlt" & @CRLF
    ;for $x = 0 to 3
    ;   $res &= $x & "  " & $aResult[$x] & @CRLF
    ;Next
    ;ConsoleWrite($res & @CRLF)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_TransparentBlt    
    
;GetPixel(
;  HDC hdc,     // handle to DC
;  int X,       // x-coordinate of pixel
;  int Y,       // y-coordinate of pixel
;Returns:     A color in the format 0xAARRGGBB (Alpha, Red, Green, Blue)
Func GetPixel ($handle, $x, $y)
    Local $dc, $icolor,$iRet
    $dc= DllCall ("user32.dll", "int", "GetDC", "hwnd", $handle)
     $icolor = DllCall ("gdi32.dll", "long", "GetPixel", "hwnd", $dc[0], "int", $x, "int", $y)
     DllCall ("user32.dll", "int", "ReleaseDC", "hwnd", 0,  "int", $dc[0])   
     ; Converts RGB to BGR colour and visa-versa
     $iRet = BitAND(BitShift(String(Binary($iColor[0])), 8), 0xFFFFFF) ; Converts RGB to BGR colour and visa-versa
     Return  "0xFF" & Hex($iRet, 6) 
 EndFunc
    
; Author(s):       Prog@ndy
Func _GDIPlus_ImageCreateGDICompatibleHBITMAP($hImg)
    Local $hBitmap2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImg)
    Local $hBitmap  = _WinAPI_CopyImage($hBitmap2, 0, 0, 0, $LR_COPYDELETEORG + $LR_COPYRETURNORG)
    _WinAPI_DeleteObject($hBitmap2)
    Return $hBitmap
EndFunc   ;==>_GDIPlus_ImageCreateGDICompatibleHBITMAP


; Author(s):       Prog@ndy
Func _WinAPI_CopyImage($hImg, $uType = 0, $x = 0, $y = 0, $flags = 0)
    Local $aResult
    $aResult = DllCall("User32.dll", "hwnd", "CopyImage", "hwnd", $hImg, "UINT", $uType, _
                                                        "int", $x, "int", $y, "UINT", $flags)
   
    _WinAPI_Check("_WinAPI_CopyImage", ($aResult[0] = 0), 0, True)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_CopyImage


; http://msdn.microsoft.com/en-us/library/ms534041(VS.85).aspx
; GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters* encoderParams)
;
Func GDIPlus_SaveAdd( $hImage, $sFileExtension)
    Local $pGUID, $tGUID, $aResult, $res
    $sCLSID = _GDIPlus_EncodersGetCLSID($sFileExtension)
    $tGUID = _WinAPI_GUIDFromString($sCLSID)
    $pGUID = DllStructGetPtr($tGUID)
    $aResult = DllCall($ghGDIPDll, "int", "GdipSaveAdd", "hwnd", $hImage, "ptr", $pGUID)
    ;$res = "GdipSaveAdd " & @CRLF
    ; for $x = 0 to 2
    ;$res &= $x & "  " & $aResult[$x] & @CRLF
    ; Next
    ;ConsoleWrite($res & @CRLF)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[2] ; SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc 

; http://msdn.microsoft.com/en-us/library/ms534041(VS.85).aspx
;GdipSaveAddImage(GpImage *image, GpImage* newImage, GDIPCONST EncoderParameters* encoderParams)
Func GDIPlus_SaveAddImage( $hImage, $sFileExtension)
    Local $pGUID, $tGUID, $aResult, $res
    $sCLSID = _GDIPlus_EncodersGetCLSID ($sFileExtension)
    $tGUID = _WinAPI_GUIDFromString($sCLSID)
    $pGUID = DllStructGetPtr($tGUID)
    $aResult = DllCall($ghGDIPDll, "int", "GdipSaveAddImage", "hwnd", $hImage, "int*", 0, "ptr", $pGUID)
    ;$res = "GdipSaveAddImage " & @CRLF
    ; for $x = 0 to 3
   ; $res &= $x & "  " & $aResult[$x] & @CRLF
   ;  Next
    ;ConsoleWrite($res & @CRLF)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[3] ; SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc         

; Ref: http://msdn.microsoft.com/en-us/library/ms532324(VS.85).aspx
Func GDIPlus_AlphaBlend($hDestDC, $iXDest, $iYDest, $iWidthDest, $iHeightDest, $hSrcDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc)
    Local Const $AC_SRC_ALPHA = 1
    Local $aResult,$res
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", 255)    
    DllStructSetData($tBlend, "Format", 1)
    $aResult = DllCall("GDI32.dll", "int", "AlphaBlend", _
                                   "hwnd", $hDestDC, _
                                    "int", $iXDest, _
                                    "int", $iYDest, _
                                    "int", $iWidthDest, _
                                    "int", $iHeightDest, _
                                   "hwnd", $hSrcDC, _
                                    "int", $iXSrc, _
                                    "int", $iYSrc, _
                                    "int", $iWidthSrc, _
                                    "int", $iHeightSrc, _
                                    "int", $pBlend) 
    If @error Then Return SetError(@error, 0, False)                                
    ;$res = "AlphaBlend " & @CRLF
    ;for $x = 0 to 5
    ;   $res &= $x & "  " & $aResult[$x] & @CRLF
    ; Next
    ;ConsoleWrite($res & @CRLF) 
    Return $aResult[3] ; SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

Notice on the GUI all the parts that were white are transparent. But on the image file the white is still white and not the background color of the viewer.

If you press "Esc" to exit layered GUI, the created PNG file on Desktop will delete.

Share this post


Link to post
Share on other sites



My objective is to specify a color in a multi-colored image to be transparent. Then, to save that resultant image to an image file. The image file when viewed would appear to have transparent parts where the specified color used to be.

And, this process is done really fast.

Summary

I am after a fast way of saving to file, a GUI with transparent parts.

My problem and what I need help with is the transparent parts will not appear in the saved image file (a PNG image file).

I am open to all suggestions. Another method, maybe.

My attempt :-

#include <Constants.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
; http://www.autoitscript.com/forum/index.php?s=&showtopic=56481&view=findpost&p=428717
;Local Const $ULW_ALPHA = 2
Global $iTransparentColor  = 0xFFFFFFFF ;= 0xFF000000;= 0x3A6EA5;  ;  = 0xD4D0C8 ;= 0xFFB0C4DE;
Global $iWidth, $iHeight,$hBitmap,$hBitmap1,$hBitmap2,$GuiSizeX = 400, $GuiSizeY = 400
;GUISetBkColor($iTransparentColor)
$hGUI2 = GUICreate("$hGUI2", $GuiSizeX, $GuiSizeY, -1, -1, 0, ($WS_EX_LAYERED)); -1, -1, 420, 10,$WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) ;-1, $WS_EX_LAYERED)

GUISetState(@SW_SHOW)

WinSetTrans($hGUI2, "", 254)
_GDIPlus_Startup()
$hBitmap = _ScreenCapture_Capture("",0,0, $GuiSizeX, $GuiSizeY, False)
$hImage2   = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
$iWidth   = _GDIPlus_ImageGetWidth($hImage2)
$iHeight  = _GDIPlus_ImageGetHeight($hImage2)
$aWinPos = WinGetPos("$hGUI2")
WinMove("$hGUI2", "", $aWinPos[0], $aWinPos[1], $iWidth, $iHeight)
_GDIPlus_ImageDispose($hImage2)
$hDDC2 = _WinAPI_GetDC($hGUI2)
$hCDC2 = _WinAPI_CreateCompatibleDC($hDDC2)
_WinAPI_SelectObject($hCDC2,$hBitmap)
$hImage2   = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
ConsoleWrite("$hImage2 " & hex($hImage2) & @CRLF)
;$hGraphics2 = _GDIPlus_GraphicsCreateFromHDC($hCDC2)
;ConsoleWrite("$hGraphics2 " & $hGraphics2  &@CRLF)

;_GDIPlus_GraphicsDrawImage($hGraphics2, $hImage2, 0, 0)
;_WinAPI_BitBlt($hDDC2, 0, 0, $iWidth, $iHeight, $hCDC2, 0, 0, $SRCCOPY ); $SRCINVERT) ; $SRCAND); $NOTSRCCOPY); 
;GDIPlus_AlphaBlend($hDDC2, 0, 0, $iWidth, $iHeight, $hCDC2,0, 0, $iWidth, $iHeight)
if Not IsNumber($iTransparentColor) Then $iTransparentColor = "0x" & Hex(PixelGetColor(3,3,$hGUI2),6) ;GetPixel($hGUI2,3,3)
ConsoleWrite("$iTransparentColorDeclared " & Hex($iTransparentColor) &@CRLF)

_WinAPI_TransparentBlt($hDDC2, 0, 0, $iWidth, $iHeight, $hCDC2, 0, 0, ($iTransparentColor))
_API_SetLayeredWindowAttributes($hGUI2, $iTransparentColor)

#cs
$tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", $iWidth)
    DllStructSetData($tSize, "Y", $iHeight)
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", 254)    ;0xFFCC8040)Alpha
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow ($hGUI2, $hDDC2, 0, $pSize, $hCDC2, $pSource, 0, $pBlend, 2) ;$ULW_COLORKEY )
#ce
$hBitmap1 = _GDIPlus_ImageCreateGDICompatibleHBITMAP($hImage2)
ConsoleWrite("$hBitmap1 " & $hBitmap1 &@CRLF)
$hImage1   = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)
ConsoleWrite("$hImage1 " & $hImage1 &@CRLF)

$sCLSID = _GDIPlus_EncodersGetCLSID ("PNG")

;$tData = DllStructCreate("int Data")
;DllStructSetData($tData, "Data", 0)
;$tParams = _GDIPlus_ParamInit (1)
;_GDIPlus_ParamAdd ($tParams, $GDIP_EPGCOLORDEPTH , 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))

_GDIPlus_ImageSaveToFileEx ($hImage1, @DesktopDir & "\TestWrite.png",$sCLSID) ;,DllStructGetPtr($tParams))
ShellExecute(@DesktopDir & "\TestWrite.png")

;_GDIPlus_GraphicsDispose($hGraphics2)
_GDIPlus_ImageDispose($hImage1)
_GDIPlus_ImageDispose($hImage2)
;_GDIPlus_ImageDispose($hImage3)
_WinAPI_DeleteObject($hBitmap)
_WinAPI_DeleteObject ($hBitmap2)
_WinAPI_DeleteObject ($hBitmap1)
_WinAPI_ReleaseDC($hGUI2, $hDDC2)
_WinAPI_DeleteDC($hCDC2)
_GDIPlus_Shutdown()

While 1
    $nMsg = GUIGetMsg()
    sleep(20)
    
    Switch $nMsg    
        Case $GUI_EVENT_CLOSE
            FileDelete(@DesktopDir & "\TestWrite.png")
            Exit
    EndSwitch
WEnd
Exit

Func _API_SetLayeredWindowAttributes($hwnd, $i_transcolor, $Transparency = 255, $isColorRef = False)   
    Local Const $AC_SRC_ALPHA = 1
    Local Const $ULW_ALPHA = 2
    Local Const $LWA_ALPHA = 0x2
    Local Const $LWA_COLORKEY = 0x1
    If Not $isColorRef Then
        $i_transcolor = Hex(String($i_transcolor), 6)
        $i_transcolor = Execute('0x00' & StringMid($i_transcolor, 5, 2) & StringMid($i_transcolor, 3, 2) & StringMid($i_transcolor, 1, 2))
    EndIf
    Local $Ret = DllCall("user32.dll", "int", "SetLayeredWindowAttributes", _
                                      "hwnd", $hwnd, _
                                      "long", $i_transcolor, _
                                      "byte", $Transparency, _
                                      "long", BitOR($LWA_COLORKEY , $LWA_ALPHA))
    Select
        Case @error
            Return SetError(@error,0,0)
        Case $ret[0] = 0
            Return SetError(4,0,0)
        Case Else
            Return 1
    EndSelect
EndFunc   ;==>_API_SetLayeredWindowAttributes

Func _WinAPI_TransparentBlt($hDestDC, $iXDest, $iYDest, $iWidth, $iHeight, $hSrcDC, $iXSrc, $iYSrc,$iColor)
    Local $aResult
    $iColor = hex($iColor,6)
    $aResult = DllCall("GDI32.dll", "int", "GdiTransparentBlt", _
                                   "hwnd", $hDestDC, _
                                    "int", $iXDest, _
                                    "int", $iYDest, _
                                    "int", $iWidth, _
                                    "int", $iHeight, _
                                   "hwnd", $hSrcDC, _
                                    "int", $iXSrc, _
                                    "int", $iYSrc, _
                                    "int", $iWidth, _
                                    "int", $iHeight, _
                                    "int", $iColor)
    If @error Then Return SetError(@error, 0, False)
    ;$res = "GdiTransparentBlt" & @CRLF
    ;for $x = 0 to 3
    ;   $res &= $x & "  " & $aResult[$x] & @CRLF
    ;Next
    ;ConsoleWrite($res & @CRLF)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_TransparentBlt    
    
;GetPixel(
;  HDC hdc,     // handle to DC
;  int X,       // x-coordinate of pixel
;  int Y,       // y-coordinate of pixel
;Returns:     A color in the format 0xAARRGGBB (Alpha, Red, Green, Blue)
Func GetPixel ($handle, $x, $y)
    Local $dc, $icolor,$iRet
    $dc= DllCall ("user32.dll", "int", "GetDC", "hwnd", $handle)
     $icolor = DllCall ("gdi32.dll", "long", "GetPixel", "hwnd", $dc[0], "int", $x, "int", $y)
     DllCall ("user32.dll", "int", "ReleaseDC", "hwnd", 0,  "int", $dc[0])   
     ; Converts RGB to BGR colour and visa-versa
     $iRet = BitAND(BitShift(String(Binary($iColor[0])), 8), 0xFFFFFF) ; Converts RGB to BGR colour and visa-versa
     Return  "0xFF" & Hex($iRet, 6) 
 EndFunc
    
; Author(s):       Prog@ndy
Func _GDIPlus_ImageCreateGDICompatibleHBITMAP($hImg)
    Local $hBitmap2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImg)
    Local $hBitmap  = _WinAPI_CopyImage($hBitmap2, 0, 0, 0, $LR_COPYDELETEORG + $LR_COPYRETURNORG)
    _WinAPI_DeleteObject($hBitmap2)
    Return $hBitmap
EndFunc   ;==>_GDIPlus_ImageCreateGDICompatibleHBITMAP


; Author(s):       Prog@ndy
Func _WinAPI_CopyImage($hImg, $uType = 0, $x = 0, $y = 0, $flags = 0)
    Local $aResult
    $aResult = DllCall("User32.dll", "hwnd", "CopyImage", "hwnd", $hImg, "UINT", $uType, _
                                                        "int", $x, "int", $y, "UINT", $flags)
   
    _WinAPI_Check("_WinAPI_CopyImage", ($aResult[0] = 0), 0, True)
    Return $aResult[0]
EndFunc   ;==>_WinAPI_CopyImage


; http://msdn.microsoft.com/en-us/library/ms534041(VS.85).aspx
; GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters* encoderParams)
;
Func GDIPlus_SaveAdd( $hImage, $sFileExtension)
    Local $pGUID, $tGUID, $aResult, $res
    $sCLSID = _GDIPlus_EncodersGetCLSID($sFileExtension)
    $tGUID = _WinAPI_GUIDFromString($sCLSID)
    $pGUID = DllStructGetPtr($tGUID)
    $aResult = DllCall($ghGDIPDll, "int", "GdipSaveAdd", "hwnd", $hImage, "ptr", $pGUID)
    ;$res = "GdipSaveAdd " & @CRLF
    ; for $x = 0 to 2
    ;$res &= $x & "  " & $aResult[$x] & @CRLF
    ; Next
    ;ConsoleWrite($res & @CRLF)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[2] ; SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc 

; http://msdn.microsoft.com/en-us/library/ms534041(VS.85).aspx
;GdipSaveAddImage(GpImage *image, GpImage* newImage, GDIPCONST EncoderParameters* encoderParams)
Func GDIPlus_SaveAddImage( $hImage, $sFileExtension)
    Local $pGUID, $tGUID, $aResult, $res
    $sCLSID = _GDIPlus_EncodersGetCLSID ($sFileExtension)
    $tGUID = _WinAPI_GUIDFromString($sCLSID)
    $pGUID = DllStructGetPtr($tGUID)
    $aResult = DllCall($ghGDIPDll, "int", "GdipSaveAddImage", "hwnd", $hImage, "int*", 0, "ptr", $pGUID)
    ;$res = "GdipSaveAddImage " & @CRLF
    ; for $x = 0 to 3
   ; $res &= $x & "  " & $aResult[$x] & @CRLF
   ;  Next
    ;ConsoleWrite($res & @CRLF)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[3] ; SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc         

; Ref: http://msdn.microsoft.com/en-us/library/ms532324(VS.85).aspx
Func GDIPlus_AlphaBlend($hDestDC, $iXDest, $iYDest, $iWidthDest, $iHeightDest, $hSrcDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc)
    Local Const $AC_SRC_ALPHA = 1
    Local $aResult,$res
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", 255)    
    DllStructSetData($tBlend, "Format", 1)
    $aResult = DllCall("GDI32.dll", "int", "AlphaBlend", _
                                   "hwnd", $hDestDC, _
                                    "int", $iXDest, _
                                    "int", $iYDest, _
                                    "int", $iWidthDest, _
                                    "int", $iHeightDest, _
                                   "hwnd", $hSrcDC, _
                                    "int", $iXSrc, _
                                    "int", $iYSrc, _
                                    "int", $iWidthSrc, _
                                    "int", $iHeightSrc, _
                                    "int", $pBlend) 
    If @error Then Return SetError(@error, 0, False)                                
    ;$res = "AlphaBlend " & @CRLF
    ;for $x = 0 to 5
    ;   $res &= $x & "  " & $aResult[$x] & @CRLF
    ; Next
    ;ConsoleWrite($res & @CRLF) 
    Return $aResult[3] ; SetError($aResult[0], 0, $aResult[0] = 0)
EndFuncoÝ÷ ØÚ-ǨØ^B[az«¶ËajÜ­ì!×­ëkj{)j·§´­¢{az)çâëa{bµè¬²Ø¥bµæ§vz-¶iÉ ®§uÊ%¢º¶¯ì¬ò¢êkzË*ºD±Ê®¢Ûh{­¬­çFPayÊÞj×

You notice I left the last param out of the call.. I think that's not correct either.

I think the last param is spose to be the Encoder Parameter not just a direct ptr to the GUID structure... I could be wrong on this part.

When I look at the msdn set up of the Encoder Param it sorta got me lost

// An EncoderParameters object has an array of
   // EncoderParameter objects. In this case, there is only
   // one EncoderParameter object in the array.
   encoderParameters.Count = 1;

   // Initialize the one EncoderParameter object.
   encoderParameters.Parameter[0].Guid = EncoderSaveFlag;
   encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
   encoderParameters.Parameter[0].NumberOfValues = 1;
   encoderParameters.Parameter[0].Value = &parameterValue;

To me it looked like the Encoder param would be more like the $tagGDIPPENCODERPARAMS stucture...

Cheers

Share this post


Link to post
Share on other sites

Sorry I don't have an answer to your question, but there are some things in your SaveAddImage translation that don't seem quite right..

Well that answers one of my questions. Everyone doesn't know except me.

This GdipSaveAddImage wrapper appears to be working now - no error & returns a handle that doesn't produce errors. I am 50% 1% certain it is working properly.

The other wrapper for "GdiTransparentBlt" from GDI32.dll file has a strange behavior. No matter how the transparent color is entered, its use causes all the black color in the image to vanish -.not transparent but rubbed out.

I made those wrapper when I was following the most fantasyful, logical directions I could think of that might work.

; http://msdn.microsoft.com/en-us/library/ms534041(VS.85).aspx
;GdipSaveAddImage(GpImage *image, GpImage* newImage, GDIPCONST EncoderParameters* encoderParams)
Func GDIPlus_SaveAddImage( $hImage)
    Local  $aResult, $res,$hImageNew,$para
    
   $tData = DllStructCreate("int Data")
    DllStructSetData($tData, "Data", $GDIP_EPGTRANSFORMATION)
   $tParams = _GDIPlus_ParamInit(1)
    _GDIPlus_ParamAdd( $tParams, $GDIP_EPGTRANSFORMATION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))   
    $aResult = DllCall($ghGDIPDll, "int", "GdipSaveAddImage", "ptr", $hImage, "int_ptr", $hImageNew,  "int_ptr", DllStructGetPtr($tParams))
    ;$res = "GdipSaveAddImage " & @CRLF
     ;for $x = 0 to 3
    ;   $res &= $x & "  " & $aResult[$x] & @CRLF
    ;Next
    ;$res &=    "$hImageNew  " & $hImageNew & @CRLF
    ; for $x = 0 to 9
    ;$res &=    "_GDIPlus_ParamAdd " & $x & "   " & DllStructGetData($tParams, $x) & @CRLF
    ;Next
    ;ConsoleWrite($res & @CRLF)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[3] ;$hImageNew ; SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Your close to it, but your setting the wrong constant to the struct eg:

DllStructSetData($tData, "Data", $GDIP_EPGTRANSFORMATION)

; I could be wrong but when I look at the Constants for the Encoder Value Type choice is:
; Note: There are some more but these are just a copy and paste from GDIPlusConstants.au3.
Global Const $GDIP_EVTCOMPRESSIONLZW = 2             ; TIFF: LZW compression
Global Const $GDIP_EVTCOMPRESSIONCCITT3 = 3             ; TIFF: CCITT3 compression
Global Const $GDIP_EVTCOMPRESSIONCCITT4 = 4             ; TIFF: CCITT4 compression
Global Const $GDIP_EVTCOMPRESSIONRLE = 5             ; TIFF: RLE compression
Global Const $GDIP_EVTCOMPRESSIONNONE = 6             ; TIFF: No compression
Global Const $GDIP_EVTTRANSFORMROTATE90 = 13            ; JPEG: Lossless 90 degree clockwise rotation
Global Const $GDIP_EVTTRANSFORMROTATE180 = 14            ; JPEG: Lossless 180 degree clockwise rotation
Global Const $GDIP_EVTTRANSFORMROTATE270 = 15            ; JPEG: Lossless 270 degree clockwise rotation
Global Const $GDIP_EVTTRANSFORMFLIPHORIZONTAL = 16            ; JPEG: Lossless horizontal flip
Global Const $GDIP_EVTTRANSFORMFLIPVERTICAL = 17            ; JPEG: Lossless vertical flip
Global Const $GDIP_EVTMULTIFRAME = 18            ; Multiple frame encoding
Global Const $GDIP_EVTLASTFRAME = 19            ; Last frame of a multiple frame image
Global Const $GDIP_EVTFLUSH = 20            ; The encoder object is to be closed
Global Const $GDIP_EVTFRAMEDIMENSIONPAGE = 23            ; TIFF: Page frame dimension

; the ones that aren't in GDIPlusConstants.au3:
Global Const $GDIP_EVTColorTypeCMYK  =  0 
Global Const $GDIP_EVTColorTypeYCCK  = 1
Global Const $GDIP_EVTScanMethodInterlaced = 7 
Global Const $GDIP_EVTScanMethodNonInterlaced = 8 
Global Const $GDIP_EVTVersionGif87 = 9 
Global Const $GDIP_EVTVersionGif89  = 10
Global Const $GDIP_EVTRenderProgressive =  11 
Global Const $GDIP_EVTRenderNonprogressive = 12  
Global Const $GDIP_EVTFrameDimensionTime = 21

Myself I use $GDIP_EVTMULTIFRAME, $GDIP_EVTFRAMEDIMENSIONPAGE and $GDIP_EVTFLUSH in combination with GdipSaveAddImage and GdipSaveAdd to put multiple images into 1 tif file (create a multi page tif).

I can post an example of the way I use it if you like?

Cheers

Edited by smashly

Share this post


Link to post
Share on other sites

I can post an example of the way I use it if you like?

An example in AutoIt would be fantastic - very helpful.

Post away, please.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Hi, crude example

#include <GDIPlus.au3>

_MakeMyMultiPageTif(@ScriptDir & "\TestMultiPage.tif")

Func _MakeMyMultiPageTif($sOutFile)
    Local $sPath = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") & "\Examples\GUI\Advanced\Images"
    Local $sCLSID, $tData, $tParams, $hImage1, $hImage2, $hImage3    
    
    _GDIPlus_Startup()
    
    $sCLSID = _GDIPlus_EncodersGetCLSID ("TIF")

    ; Create the Const Encoder Value Type struct
    $tData = DllStructCreate("int Data")
    
    ; Put the Const Encoder Value Type into the struct
    DllStructSetData($tData, "Data", $GDIP_EVTMULTIFRAME)
    
    ;Initiate the Encoder Parameters
    $tParams = _GDIPlus_ParamInit (1)
    _GDIPlus_ParamAdd ($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))

    ; Load 3 images that will be put into the tif file, the images can be different formats and sizes. 
    $hImage1 = _GDIPlus_ImageLoadFromFile($sPath & "\Red.bmp")
    $hImage2 = _GDIPlus_ImageLoadFromFile($sPath & "\Green.bmp")
    $hImage3 = _GDIPlus_ImageLoadFromFile($sPath & "\Blue.bmp")

    ; Save the first loaded image passing on the Encoder Parameters
    _GDIPlus_ImageSaveToFileEx($hImage1, $sOutFile, $sCLSID, DllStructGetPtr($tParams))

    ; Now we have saved the first image into the tif we can set the Encoder Value Type again to add the next frames
    DllStructSetData($tData, "Data", $GDIP_EVTFRAMEDIMENSIONPAGE)
    $tParams = _GDIPlus_ParamInit (1)
    _GDIPlus_ParamAdd ($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))

    ; Now we add the 2nd frame
    _GDIPlus_ImageSaveAddImage($hImage1, $hImage2, DllStructGetPtr($tParams))
    
    ; Now we add the 3rd frame
    _GDIPlus_ImageSaveAddImage($hImage1, $hImage3, DllStructGetPtr($tParams))

    ; My images are now added to the tif file I want to set the Encoder Value Type again to flush and finalise
    DllStructSetData($tData, "Data", $GDIP_EVTFLUSH)
    $tParams = _GDIPlus_ParamInit (1)
    _GDIPlus_ParamAdd ($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))
    
    ; Now the final step to flush the encoder and finalize the image
    _GDIPlus_ImageSaveAdd($hImage1, DllStructGetPtr($tParams))

    ; Tidy up the 3 images we loaded and shutdown.
    _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_ImageDispose($hImage2)
    _GDIPlus_ImageDispose($hImage3)
    _GDIPlus_Shutdown()
EndFunc

Func _GDIPlus_ImageSaveAddImage($hImage, $hImageNew, $pParams)
    Local $aResult
    
    $aResult = DllCall($ghGDIPDll, "int", "GdipSaveAddImage", "hwnd", $hImage, "hwnd", $hImageNew, "ptr", $pParams)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

Func _GDIPlus_ImageSaveAdd($hImage, $pParams)
    Local $aResult
    
    $aResult = DllCall($ghGDIPDll, "int", "GdipSaveAdd", "hwnd", $hImage, "ptr", $pParams)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

To view the multi-page tif just open it in windows picture fax viewer.

Cheers

Edited by smashly

Share this post


Link to post
Share on other sites

Hi, crude example

#include <GDIPlus.au3>

_MakeMyMultiPageTif(@ScriptDir & "\TestMultiPage.tif")

Func _MakeMyMultiPageTif($sOutFile)
    Local $sPath = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") & "\Examples\GUI\Advanced\Images"
    Local $sCLSID, $tData, $tParams, $hImage1, $hImage2, $hImage3    
    
    _GDIPlus_Startup()
    
    $sCLSID = _GDIPlus_EncodersGetCLSID ("TIF")

    ; Create the Const Encoder Value Type struct
    $tData = DllStructCreate("int Data")
    
    ; Put the Const Encoder Value Type into the struct
    DllStructSetData($tData, "Data", $GDIP_EVTMULTIFRAME)
    
    ;Initiate the Encoder Parameters
    $tParams = _GDIPlus_ParamInit (1)
    _GDIPlus_ParamAdd ($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))

    ; Load 3 images that will be put into the tif file, the images can be different formats and sizes. 
    $hImage1 = _GDIPlus_ImageLoadFromFile($sPath & "\Red.bmp")
    $hImage2 = _GDIPlus_ImageLoadFromFile($sPath & "\Green.bmp")
    $hImage3 = _GDIPlus_ImageLoadFromFile($sPath & "\Blue.bmp")

    ; Save the first loaded image passing on the Encoder Parameters
    _GDIPlus_ImageSaveToFileEx($hImage1, $sOutFile, $sCLSID, DllStructGetPtr($tParams))

    ; Now we have saved the first image into the tif we can set the Encoder Value Type again to add the next frames
    DllStructSetData($tData, "Data", $GDIP_EVTFRAMEDIMENSIONPAGE)
    $tParams = _GDIPlus_ParamInit (1)
    _GDIPlus_ParamAdd ($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))

    ; Now we add the 2nd frame
    _GDIPlus_ImageSaveAddImage($hImage1, $hImage2, DllStructGetPtr($tParams))
    
    ; Now we add the 3rd frame
    _GDIPlus_ImageSaveAddImage($hImage1, $hImage3, DllStructGetPtr($tParams))

    ; My images are now added to the tif file I want to set the Encoder Value Type again to flush and finalise
    DllStructSetData($tData, "Data", $GDIP_EVTFLUSH)
    $tParams = _GDIPlus_ParamInit (1)
    _GDIPlus_ParamAdd ($tParams, $GDIP_EPGSAVEFLAG, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))
    
    ; Now the final step to flush the encoder and finalize the image
    _GDIPlus_ImageSaveAdd($hImage1, DllStructGetPtr($tParams))

    ; Tidy up the 3 images we loaded and shutdown.
    _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_ImageDispose($hImage2)
    _GDIPlus_ImageDispose($hImage3)
    _GDIPlus_Shutdown()
EndFunc

Func _GDIPlus_ImageSaveAddImage($hImage, $hImageNew, $pParams)
    Local $aResult
    
    $aResult = DllCall($ghGDIPDll, "int", "GdipSaveAddImage", "hwnd", $hImage, "hwnd", $hImageNew, "ptr", $pParams)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

Func _GDIPlus_ImageSaveAdd($hImage, $pParams)
    Local $aResult
    
    $aResult = DllCall($ghGDIPDll, "int", "GdipSaveAdd", "hwnd", $hImage, "ptr", $pParams)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc

To view the multi-page tif just open it in windows picture fax viewer.

Cheers

This is a good example. It works.

And a good tip about viewing a multi-page tif file in windows picture fax viewer.

Thanks for sharing.

Share this post


Link to post
Share on other sites

Glad you like it and sorry it doesn't help you with the saving transparency.

I've submitted the functions and example to the bugtrak as a request to add the functions to the gdiplus udf.

It's not something that would be used that often by most ppl, but I can't see any reason why it shouldn't be added.

Cheers

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  
Followers 0