Jump to content

Stretch png and then use it as GUI


TrueSR
 Share

Recommended Posts

Hi all,

I'm experimenting with png's as GUI's, but i have a question :

Is it possible to stretch a png file and then use it as GUI ?

Example to explain a bit more :

I have a nice png here :

Posted Image

Script (thanks lod3n, PaulIA and GaryFrost) :

#include <GDIPlus.au3>; this is where the magic happens, people
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>

Opt("MustDeclareVars", 0)

Global Const $AC_SRC_ALPHA = 1
;~ Global Const $ULW_ALPHA       = 2

; Load PNG file as GDI bitmap
_GDIPlus_Startup()
$pngSrc = @ScriptDir & "\back.png"
$hImage = _GDIPlus_ImageLoadFromFile($pngSrc)

; Extract image width and height from PNG
$width = _GDIPlus_ImageGetWidth($hImage)
$height = _GDIPlus_ImageGetHeight($hImage)

; Create layered window
$GUI = GUICreate("Test GUI", $width, $height, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
SetBitmap($GUI, $hImage, 255)
; Register notification messages
GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
GUISetState()
WinSetOnTop($GUI, "", 1)


; create child MDI gui window to hold controls
; this part could use some work - there is some flicker sometimes...
$controlGui = GUICreate("ControlGUI", $width, $height, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $GUI)

; child window transparency is required to accomplish the full effect, so $WS_EX_LAYERED above, and
; I think the way this works is the transparent window color is based on the image you set here:
GUICtrlCreatePic(@ScriptDir & "\grey.gif", 0, 0, $width, $height)
GUICtrlSetState(-1, $GUI_DISABLE)


GUISetState()


While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
    EndSelect
WEnd


GUIDelete($controlGui)

; Release resources
_WinAPI_DeleteObject($hImage)
_GDIPlus_Shutdown()



; ====================================================================================================



; Handle the WM_NCHITTEST for the layered window so it can be dragged by clicking anywhere on the image.
; ====================================================================================================



Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
    If ($hWnd = $GUI) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION
EndFunc ;==>WM_NCHITTEST

; ====================================================================================================



; SetBitMap
; ====================================================================================================



Func SetBitmap($hGUI, $hImage, $iOpacity)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc ;==>SetBitmap

Here is the grey.gif :

Posted Image

So i want the GUI about 500 pixels width.

It would be even greater if it is possible to take the center of the png and stretch that,

so you still have the nice left and right side of the png.

Thanks

Edited by TrueSR
Link to comment
Share on other sites

You can resize the image before use like this (at the end of script you can delete the new image):

#include <GDIPlus.au3>; this is where the magic happens, people
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>

Opt("MustDeclareVars", 0)

Global Const $AC_SRC_ALPHA = 1
;~ Global Const $ULW_ALPHA       = 2

; Load PNG file as GDI bitmap
_GDIPlus_Startup()
$pngSrc = @ScriptDir & "\back.png"
$hImage = _GDIPlus_ImageLoadFromFile($pngSrc)

; Extract image width and height from PNG
$width = _GDIPlus_ImageGetHeight($hImage)
$height = _GDIPlus_ImageGetHeight($hImage)

If $width < 500 Then
    _ImageResize(@ScriptDir & "\back.png",@ScriptDir & "\resize_back.png",500, $height)
    $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\resize_back.png")
    $width = _GDIPlus_ImageGetHeight($hImage)
    $height = _GDIPlus_ImageGetHeight($hImage)
EndIf

; Create layered window
$GUI = GUICreate("Test GUI", $width, $height, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
SetBitmap($GUI, $hImage, 255)
; Register notification messages
GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
GUISetState()
WinSetOnTop($GUI, "", 1)


; create child MDI gui window to hold controls
; this part could use some work - there is some flicker sometimes...
$controlGui = GUICreate("ControlGUI", $width, $height, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $GUI)

; child window transparency is required to accomplish the full effect, so $WS_EX_LAYERED above, and
; I think the way this works is the transparent window color is based on the image you set here:
GUICtrlCreatePic(@ScriptDir & "\grey.gif", 0, 0, $width, $height)
GUICtrlSetState(-1, $GUI_DISABLE)


GUISetState()


While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
    EndSelect
WEnd


GUIDelete($controlGui)

; Release resources
_WinAPI_DeleteObject($hImage)
_GDIPlus_Shutdown()



; ====================================================================================================




; Handle the WM_NCHITTEST for the layered window so it can be dragged by clicking anywhere on the image.
; ====================================================================================================




Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
    If ($hWnd = $GUI) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION
EndFunc;==>WM_NCHITTEST

; ====================================================================================================




; SetBitMap
; ====================================================================================================




Func SetBitmap($hGUI, $hImage, $iOpacity)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc;==>SetBitmap

Func _ImageResize($sInImage, $sOutImage, $newW, $newH)
    Local $oldImage, $GC, $newBmp, $newGC
    _GDIPlus_Startup()
   ; Load Image
    $oldImage = _GDIPlus_ImageLoadFromFile($sInImage)
   ;Create New image
    $GC = _GDIPlus_ImageGetGraphicsContext($oldImage)
    $newBmp = _GDIPlus_BitmapCreateFromGraphics($newW, $newH, $GC)
    $newGC = _GDIPlus_ImageGetGraphicsContext($newBmp)
   ;Draw
    _GDIPlus_GraphicsDrawImageRect($newGC, $oldImage, 0, 0, $newW, $newH)
    _GDIPlus_ImageSaveToFile($newBmp, $sOutImage)
   ;Clenaup
    _GDIPlus_GraphicsDispose($GC)
    _GDIPlus_GraphicsDispose($newGC)
    _GDIPlus_BitmapDispose($newBmp)
    _GDIPlus_ImageDispose($oldImage)
    _GDIPlus_Shutdown()
EndFunc  ;==>_ImageResize

When the words fail... music speaks.

Link to comment
Share on other sites

Thanks ! Works great !

And you can get the center of the image with _GDIPlus_BitmapCloneArea right ?

I don't know about what center are you talking.

The center of image should be:

$X = Width/2

$Y = Height/2

If I`m wrong please correct me. Or you want to say something else.

When the words fail... music speaks.

Link to comment
Share on other sites

I mean this piece :

Posted Image

Cut away 40 pixels from the left and 40 from the right.

Sorry if it wasn't clear.

No need to say sorry. Now I understand what you want to say.

If you look in GDIPlus.au3 you`ll see that _GDIPlus_GraphicsDrawImageRect use function GdipDrawImageRectI from GDIPlus.dll ,no _GDIPlus_BitmapCloneArea, to resize the picture.

When the words fail... music speaks.

Link to comment
Share on other sites

No need to say sorry. Now I understand what you want to say.

If you look in GDIPlus.au3 you`ll see that _GDIPlus_GraphicsDrawImageRect use function GdipDrawImageRectI from GDIPlus.dll ,no _GDIPlus_BitmapCloneArea, to resize the picture.

Oké, thank you very much, you solved my question very fast :mellow: !

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...