Jump to content

image resize in gui, WS_SIZEBOX resize form with full image


Recommended Posts

I have a problem with my resize form with full image script...
I have already searched the forum and I found some examples, but is not work correctly for me, so I tried to solve this problem myself.

I have a resizable Gui form, $ WS_SIZEBOX.
In this Gui, I want to display a larger image, and when I resize the GUI, the image should be proportional, without losing its clarity.
This is my script, it works relatively well, but in many cases, the image is not fully displayed.

Thanks in advance

 

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
_GDIPlus_Startup()


$IMAGINE_PATH = "C:\Users\Windows 10 Pro\Desktop\image4.jpg"

Global $IMAGINE_GDI, $LATIME, $INALTIME, $PICTURE
Global $LATIME_IMG, $INALTIME_IMG
_GetSize()

$FORM_LATIME = 0
$FORM_INALTIME = 0
$Form2 = GUICreate("TEST", 1300, 750, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP))

AdlibRegister('_StructuraImagine', 10)

GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Func _GetSize()

    $IMAGINE_GDI = _GDIPlus_ImageLoadFromFile($IMAGINE_PATH)
    $LATIME = _GDIPlus_ImageGetWidth($IMAGINE_GDI)
    $INALTIME = _GDIPlus_ImageGetHeight($IMAGINE_GDI)
    _GDIPlus_ImageDispose($IMAGINE_GDI)
    _GDIPlus_Shutdown()

EndFunc   ;==>_GetSize

Func _StructuraImagine()

    $Size = WinGetClientSize($Form2)

    If $Size[0] <> $FORM_LATIME Or $Size[1] <> $FORM_INALTIME Then
        $FORM_LATIME = $Size[0]
        $FORM_INALTIME = $Size[1]
        _Modifica_Imagine()
    EndIf

EndFunc   ;==>_StructuraImagine

Func _Modifica_Imagine()
    GUICtrlDelete($PICTURE)

    If $LATIME > $FORM_LATIME Or $INALTIME > $FORM_INALTIME Then

        If $INALTIME > $LATIME Then

            $RATIE = $LATIME / $INALTIME

            $LATIME_IMG = $FORM_INALTIME
            $INALTIME_IMG = $FORM_INALTIME

            $LATIME_IMG = $INALTIME_IMG * $RATIE

        EndIf

        If $LATIME > $INALTIME Then

            $RATIE = $LATIME / $INALTIME

            $LATIME_IMG = $FORM_LATIME
            $INALTIME_IMG = $FORM_INALTIME

            $LATIME_IMG = $INALTIME_IMG * $RATIE

        EndIf

    EndIf

    $PICTURE = GUICtrlCreatePic($IMAGINE_PATH, 0, 0, $LATIME_IMG, $INALTIME_IMG)

EndFunc   ;==>_Modifica_Imagine

 

Link to comment
Share on other sites

7 hours ago, beginner10 said:

when I resize the GUI, the image should be proportional

Not exactly sure what that means.

If the user, for example, reduce the width without changing the height, how do you expect the picture to be drawn ?  Do you want to crop the image and leave an empty space below or do you want to distort the image to fit the new dimension of the window ?

Edited by Nine
Link to comment
Share on other sites

well not sure where you would use this, except you want a fullscreen GUI without controls... i mean you would have to resize the left an top also when you want to add some.

 

anyway if i understood you right you are looking for something like

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPISysWin.au3>

Dim $__BMP[0], $__Image[0]
Local $path = @ScriptDir & "\", $pic = $path & "images.png"
Local $hPic

_GDIPlus_Startup()
$img = _GDIPlus_ImageLoadFromFile($pic)

Global $hGUImain = GUICreate("", _GDIPlus_ImageGetWidth($img),_GDIPlus_ImageGetHeight($img),-1,-1,  BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP))
GUISetBkColor(0x000000)
_SetPicToCTRL($hPic, $pic, 0, 0)
GUISetState(@SW_SHOW, $hGUImain)

While 1
    _SizeIMG($hPic)
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            For $i = 0 To UBound($__BMP) - 1
                _WinAPI_DeleteObject($__BMP)
            Next
            _GDIPlus_Shutdown()
            GUIDelete($hGUImain)
            Exit
    EndSwitch
WEnd

Func _SizeIMG( $_hCTRL)
    Local $_aWIN_Size = WinGetClientSize($hGUImain)
    Local $_aIMG_Pos = ControlGetPos ( $hGUImain,"",$_hCTRL )
    Local $Propotion = $_aIMG_Pos[2] / $_aIMG_Pos[3]
        If $_aWIN_Size[0]-10 < $_aIMG_Pos[2] Or  $_aWIN_Size[0]-10 > $_aIMG_Pos[2] Then
        $_width_diff = $_aWIN_Size[0]
        If $_width_diff/$Propotion < $_aWIN_Size[1]-10 Then GUICtrlSetPos ( $_hCTRL,$_aIMG_Pos[0],$_aIMG_Pos[1],$_width_diff,$_width_diff/$Propotion)
        EndIf
        If $_aWIN_Size[1]-10 < $_aIMG_Pos[3] Or $_aWIN_Size[1]-10 > $_aIMG_Pos[3] Then
        $_height_diff = $_aWIN_Size[1]
        If $_height_diff*$Propotion < $_aWIN_Size[0]-10 Then GUICtrlSetPos ( $_hCTRL,$_aIMG_Pos[0],$_aIMG_Pos[1],$_height_diff*$Propotion,$_height_diff)
        EndIf
EndFunc

Func _SetPicToCTRL(ByRef $_aCTRL, $_aPic_Path, $x = 5, $y = 5, $w = False, $h = False)
    Local $_w = $w, $_h = $h
    If IsArray($_aPic_Path) And IsArray($_aCTRL) Then
        For $i = 0 To UBound($_aPic_Path) - 1
            ReDim $__Image[UBound($__Image) + 1]
            ReDim $__BMP[UBound($__BMP) + 1]
            $__Image[UBound($__Image) - 1] = _GDIPlus_ImageLoadFromFile($_aPic_Path[$i])
            If @error Then Return SetError(-1, 1, -1)
            $__BMP[UBound($__BMP) - 1] = _GDIPlus_BitmapCreateHBITMAPFromBitmap($__Image[UBound($__Image) - 1])
            If @error Then Return SetError(-1, 2, -1)
            If $w = False Then $_w = _GDIPlus_ImageGetWidth($_aPic_Path[$i])
            If $h = False Then $_h = _GDIPlus_ImageGetHeight($_aPic_Path[$i])
            $_aCTRL[$i] = GUICtrlCreatePic("", 0, 0, 10, 10)
            If @error Then Return SetError(-1, 3, -1)
            _WinAPI_DeleteObject(GUICtrlSendMsg($_aCTRL[$i], $STM_SETIMAGE, $IMAGE_BITMAP, $__BMP[UBound($__BMP) - 1]))
            If @error Then Return SetError(-1, 4, -1)
            GUICtrlSetPos($_aCTRL[$i], $x, $y, $_w, $_h)
            If @error Then Return SetError(-1, 5, -1)
            If Not $i = 0 Then GUICtrlSetState($_aCTRL[$i], $GUI_HIDE)
        Next
    ElseIf IsArray($_aPic_Path) And IsArray($_aCTRL) <> True Then
        SetError(-3, 1, -3)
    ElseIf IsArray($_aCTRL) And IsArray($_aPic_Path) <> True Then
        SetError(-3, 2, -3)
    Else
        ReDim $__Image[UBound($__Image) + 1]
        ReDim $__BMP[UBound($__BMP) + 1]
        $__Image[UBound($__Image) - 1] = _GDIPlus_ImageLoadFromFile($_aPic_Path)
        If @error Then Return SetError(-2, 1, -2)
        $__BMP[UBound($__BMP) - 1] = _GDIPlus_BitmapCreateHBITMAPFromBitmap($__Image[UBound($__Image) - 1])
        If @error Then Return SetError(-2, 2, -2)
        If $w = False Then $_w = _GDIPlus_ImageGetWidth($_aPic_Path)
        If $h = False Then $_h = _GDIPlus_ImageGetHeight($_aPic_Path)
        $_aCTRL = GUICtrlCreatePic("", 0, 0, 10, 10)
        If @error Then Return SetError(-2, 3, -2)
        _WinAPI_DeleteObject(GUICtrlSendMsg($_aCTRL, $STM_SETIMAGE, $IMAGE_BITMAP, $__BMP[UBound($__BMP) - 1]))
        If @error Then Return SetError(-2, 4, -2)
        GUICtrlSetPos($_aCTRL, $x, $y, $_w, $_h)
        If @error Then Return SetError(-2, 5, -2)
    EndIf
    Return True
EndFunc   ;==>_SetPicToCTRL

btw the _SetPicToCTRL() func is for single picture paths and arrays... just took it from another script 

 

EDIT

11 hours ago, beginner10 said:

In this Gui, I want to display a larger image, and when I resize the GUI, the image should be proportional, without losing its clarity.

 

 

Hmm clarity... What do you mean? If your image has a resolution which is greater than your GUI it always should be clear :huh:

 

regards

Edited by Aelc

why do i get garbage when i buy garbage bags? <_<

Link to comment
Share on other sites

Thanks for your help!

The script is close to the truth, but it should be able to display the image at its maximum resolution, but no more than that.
For example, if an image has 960x640, the image should be displayed at maximum this resolution, not higher than that.
Basically, I would like it to behave like "windows photo viewer"
I have attached a video below: 

 

 

 

 

Link to comment
Share on other sites

Here, I think this is close to what you need.  However, it doesn't check for maximum size (I will leave that to you) :

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPISysWin.au3>

_GDIPlus_Startup()

Example()

_GDIPlus_Shutdown()

Func Example()
  Local Const $BASE_WIDTH = 800, $BASE_HEIGHT = 600
  Global $hImage = _GDIPlus_ImageLoadFromFile("Claude Grise.jpg")
  Global $iImageWidth = _GDIPlus_ImageGetWidth($hImage), $iImageHeight = _GDIPlus_ImageGetHeight($hImage)
  Local $aPos = _EvaluateSize($BASE_WIDTH, $BASE_HEIGHT, $iImageWidth, $iImageHeight)

  Global $hGUI = GUICreate("", $aPos[0], $aPos[1], -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME))
  GUISetBkColor(0x000000)
  Global $idPic = GUICtrlCreatePic("", 0, 0, $aPos[0], $aPos[1])
  Local $hBitMap = _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])

  GUIRegisterMsg($WM_SIZE, WM_SIZE)

  GUISetState()
  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  _WinAPI_DeleteObject($hBitMap)

EndFunc   ;==>Example

Func _EvaluateSize($iBaseWidth, $iBaseHeight, $iActualWidth, $iActualHeight)
  Local $iVal = $iBaseWidth / $iActualWidth * $iActualHeight
  If $iVal <= $iBaseHeight Then Return StringSplit($iBaseWidth & "|" & $iVal, "|", $STR_NOCOUNT)
  $iVal = $iBaseHeight / $iActualHeight * $iActualWidth
  Return StringSplit($iVal & "|" & $iBaseHeight, "|", $STR_NOCOUNT)
EndFunc   ;==>_EvaluateSize

Func _SetImagetoCtrl($idPic, $hImage, $iWidth, $iHeight)
  Local $hResize = _GDIPlus_ImageResize($hImage, $iWidth, $iHeight)
  Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hResize)
  _GDIPlus_ImageDispose($hResize)
  _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap))
  Return $hHBitmap
EndFunc   ;==>_SetImagetoCtrl

Func WM_SIZE($hWnd, $nMsg, $wParam, $lParam)
  AdlibRegister(_ResizeImage, 5)
  Return 1
EndFunc   ;==>WM_SIZE

Func _ResizeImage()
  AdlibUnRegister(_ResizeImage)
  Local $tRECT = _WinAPI_GetClientRect($hGUI)
  Local $iWidth = $tRECT.right - $tRECT.left + 1
  Local $iHeight = $tRECT.bottom - $tRECT.top + 1
  Local $aPos = _EvaluateSize($iWidth, $iHeight, $iImageWidth, $iImageHeight)
  _WinAPI_MoveWindow(GUICtrlGetHandle($idPic), 0, 0, $aPos[0], $aPos[1])
  $hBitMap = _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])
EndFunc   ;==>_ResizeImage

 

Edited by Nine
Link to comment
Share on other sites

Thank you for your effort.
Unfortunately, the script doesn't help me for what I need, because the pictures lose their clarity when I maximize the GUI form.
For example the picture below is 960x640, when I maximize Gui, the picture spreads across the screen, which is wrong, because my screen is much larger than the resolution of the picture.

The picture must be centered in the middle of the GUI, and displayed at its original resolution, even if the gui form is maximized, across my entire screen.

Basically, when I maximize GUI form, the picture must have the limit to increase to original resolution, no more.

It would be correct for the picture to open as in screenshot number 2.

 

 

1.jpg

2.jpg

Edited by beginner10
Link to comment
Share on other sites

It is not a big deal, only a few lines of code to add.  Like I said, I will leave it to you to check in the resize function for maximum.  Try to adapt the code and come back with what you have tried and doesn't work

Edited by Nine
Link to comment
Share on other sites

@Nine, Thanks for the help. Of course I don’t ask for direct help, I research the script and try to solve it on my own.
I changed the _ResizeImage () function, I put some ifs that check the maximum length and width, and it stops there.
Now it seems to be working properly, but there are still 2 problems.
1. The picture is not centered, I don't know how to do that.
2. When you press the maximize button, it does not work. It only works when I widen the Gui.

 

My code:

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPISysWin.au3>

_GDIPlus_Startup()

Example()

_GDIPlus_Shutdown()

Func Example()
    Local Const $BASE_WIDTH = @DesktopWidth / 2, $BASE_HEIGHT = @DesktopHeight / 2
    Global $hImage = _GDIPlus_ImageLoadFromFile("C:\Users\Windows 10 Pro\Desktop\Test\Images\2.jpg")
    Global $iImageWidth = _GDIPlus_ImageGetWidth($hImage)
    Global $iImageHeight = _GDIPlus_ImageGetHeight($hImage)

    Local $aPos = _EvaluateSize($BASE_WIDTH, $BASE_HEIGHT, $iImageWidth, $iImageHeight)

    Global $hGUI = GUICreate("", $aPos[0], $aPos[1], -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME))
    GUISetBkColor(0x000000)
    Global $idPic = GUICtrlCreatePic("", 0, 0, $aPos[0], $aPos[1])
    Local $hBitMap = _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])

    GUIRegisterMsg($WM_SIZE, WM_SIZE)

    GUISetState()
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd

    _WinAPI_DeleteObject($hBitMap)

EndFunc   ;==>Example

Func _EvaluateSize($iBaseWidth, $iBaseHeight, $iActualWidth, $iActualHeight)
    Local $iVal = $iBaseWidth / $iActualWidth * $iActualHeight
    If $iVal <= $iBaseHeight Then Return StringSplit($iBaseWidth & "|" & $iVal, "|", $STR_NOCOUNT)
    $iVal = $iBaseHeight / $iActualHeight * $iActualWidth
    Return StringSplit($iVal & "|" & $iBaseHeight, "|", $STR_NOCOUNT)
EndFunc   ;==>_EvaluateSize

Func _SetImagetoCtrl($idPic, $hImage, $iWidth, $iHeight)
    Local $hResize = _GDIPlus_ImageResize($hImage, $iWidth, $iHeight)
    Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hResize)
    _GDIPlus_ImageDispose($hResize)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap))
    Return $hHBitmap
EndFunc   ;==>_SetImagetoCtrl

Func WM_SIZE($hWnd, $nMsg, $wParam, $lParam)
    AdlibRegister(_ResizeImage, 5)
    Return 1
EndFunc   ;==>WM_SIZE

Func _ResizeImage()
    AdlibUnRegister(_ResizeImage)
    Local $tRECT = _WinAPI_GetClientRect($hGUI)
    Local $iWidth = $tRECT.right - $tRECT.left + 1
    Local $iHeight = $tRECT.bottom - $tRECT.top + 1
    Local $aPos = _EvaluateSize($iWidth, $iHeight, $iImageWidth, $iImageHeight)

    If $aPos[0] > $iImageWidth Then
        ConsoleWrite(@CRLF & "MAXIM Width" & $aPos[0] & " \ " & $iImageWidth)
    Else
        If $aPos[1] > $iImageHeight Then
            ConsoleWrite(@CRLF & "MAXIM Height" & $aPos[1] & " \ " & $iImageHeight)
        Else
            _WinAPI_MoveWindow(GUICtrlGetHandle($idPic), 0, 0, $aPos[0], $aPos[1])
            $hBitMap = _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])
            ConsoleWrite(@CRLF & "LIMIT " & $aPos[0] & " \ " & $iImageWidth)
        EndIf
    EndIf

EndFunc   ;==>_ResizeImage

 

Link to comment
Share on other sites

You are not very far, but I will give you a hand for you to study it :

Func _ResizeImage()
  AdlibUnRegister(_ResizeImage)
  Local $tRECT = _WinAPI_GetClientRect($hGUI)
  Local $iWidth = $tRECT.right - $tRECT.left + 1
  Local $iHeight = $tRECT.bottom - $tRECT.top + 1
  If $iWidth > $iImageWidth And $iHeight > $iImageHeight Then
    Local $aPos [] = [$iImageWidth, $iImageHeight]
  Else
    Local $aPos = _EvaluateSize($iWidth, $iHeight, $iImageWidth, $iImageHeight)
  EndIf
  _WinAPI_MoveWindow(GUICtrlGetHandle($idPic), Int(($iWidth-$aPos[0])/2), Int(($iHeight-$aPos[1])/2), $aPos[0], $aPos[1])
  $hBitMap = _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])
EndFunc   ;==>_ResizeImage

This will also center the image.

Link to comment
Share on other sites

@Nine

Now I understand how to center an object, easy math, but I didn't think about it.

 Int(($iWidth-$aPos[0])/2), Int(($iHeight-$aPos[1])/2

 

Thanks for the support, now everything is fine, if I need improvements I will come back here.
Have a merry christmas!

Edited by beginner10
Link to comment
Share on other sites

@beginner10  Just notice a small bug if the image is smaller than the BASE GUI.  Please replace those lines at the beginning of the example func :

Local Const $BASE_WIDTH = 800, $BASE_HEIGHT = 600
  Global $hImage = _GDIPlus_ImageLoadFromFile("Torus.jpg")
  Global $iImageWidth = _GDIPlus_ImageGetWidth($hImage), $iImageHeight = _GDIPlus_ImageGetHeight($hImage)
  Local $aPos[] = [$iImageWidth, $iImageHeight]
  If $iImageWidth > $BASE_WIDTH Or $iImageHeight > $BASE_HEIGHT Then
    $aPos = _EvaluateSize($BASE_WIDTH, $BASE_HEIGHT, $iImageWidth, $iImageHeight)
  EndIf

Merry Xmas to you too.

Edited by Nine
Link to comment
Share on other sites

I'm trying to add this script to a button.
So that when I press that button, I open a photo album.
After I added this script to the button, it doesn't work at all.
I'm trying to figure out how to solve this.

 

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPISysWin.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)


$Form1 = GUICreate("Form1", 275, 122, 192, 124)
GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
$Button1 = GUICtrlCreateButton("Album image 1", 16, 16, 115, 41)
GUICtrlSetOnEvent($Button1, "_Start")
;$Button2 = GUICtrlCreateButton("Album image 2", 16, 64, 115, 41)
GUISetState(@SW_SHOW)


While True
    Sleep(10)
WEnd

Func _Start()
    Global $hImage = _GDIPlus_ImageLoadFromFile("C:\Users\Windows 10 Pro\Desktop\Test\Images\2.jpg")
    Global $iImageWidth = _GDIPlus_ImageGetWidth($hImage), $iImageHeight = _GDIPlus_ImageGetHeight($hImage)
    Local $aPos[] = [$iImageWidth, $iImageHeight]
    If $iImageWidth > @DesktopWidth Or $iImageHeight > @DesktopHeight Then
        $aPos = _EvaluateSize(@DesktopWidth, @DesktopHeight, $iImageWidth, $iImageHeight)
    EndIf
    Global $hGUI = GUICreate("", $aPos[0], $aPos[1], -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME))
    GUISetBkColor(0x000000)
    GUISetOnEvent($hGUI, "SpecialEvents2")
    Global $idPic = GUICtrlCreatePic("", 0, 0, $aPos[0], $aPos[1])
    Global $hBitMap = _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])

    GUIRegisterMsg($WM_SIZE, WM_SIZE)

    GUISetState()
EndFunc   ;==>_Start


Func _EvaluateSize($iBaseWidth, $iBaseHeight, $iActualWidth, $iActualHeight)
    Local $iVal = $iBaseWidth / $iActualWidth * $iActualHeight
    If $iVal <= $iBaseHeight Then Return StringSplit($iBaseWidth & "|" & $iVal, "|", $STR_NOCOUNT)
    $iVal = $iBaseHeight / $iActualHeight * $iActualWidth
    Return StringSplit($iVal & "|" & $iBaseHeight, "|", $STR_NOCOUNT)
EndFunc   ;==>_EvaluateSize

Func _SetImagetoCtrl($idPic, $hImage, $iWidth, $iHeight)
    Local $hResize = _GDIPlus_ImageResize($hImage, $iWidth, $iHeight)
    Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hResize)
    _GDIPlus_ImageDispose($hResize)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap))
    Return $hHBitmap
EndFunc   ;==>_SetImagetoCtrl

Func WM_SIZE($hWnd, $nMsg, $wParam, $lParam)
    AdlibRegister(_ResizeImage, 5)
    Return 1
EndFunc   ;==>WM_SIZE

Func _ResizeImage()
    AdlibUnRegister(_ResizeImage)
    Local $tRECT = _WinAPI_GetClientRect($hGUI)
    Local $iWidth = $tRECT.right - $tRECT.left + 1
    Local $iHeight = $tRECT.bottom - $tRECT.top + 1
    If $iWidth > $iImageWidth And $iHeight > $iImageHeight Then
        Local $aPos[] = [$iImageWidth, $iImageHeight]
    Else
        Local $aPos = _EvaluateSize($iWidth, $iHeight, $iImageWidth, $iImageHeight)
    EndIf
    _WinAPI_MoveWindow(GUICtrlGetHandle($idPic), Int(($iWidth - $aPos[0]) / 2), Int(($iHeight - $aPos[1]) / 2), $aPos[0], $aPos[1])
    $hBitMap = _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])
EndFunc   ;==>_ResizeImage

Func SpecialEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            Exit
        Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
        Case @GUI_CtrlId = $GUI_EVENT_RESTORE
    EndSelect
EndFunc   ;==>SpecialEvents
Func SpecialEvents2()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            _WinAPI_DeleteObject($hBitMap)
            _GDIPlus_Shutdown()
            Exit
        Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
        Case @GUI_CtrlId = $GUI_EVENT_RESTORE
    EndSelect
EndFunc   ;==>SpecialEvents2

 

 

I think this is the way, but just doesn't work, I'm omitting something.
The latest script:

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPISysWin.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)


$Form1 = GUICreate("Form1", 275, 122, 192, 124)
GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")
$Button1 = GUICtrlCreateButton("Album image 1", 16, 16, 115, 41)
GUICtrlSetOnEvent($Button1, "_Start")
;$Button2 = GUICtrlCreateButton("Album image 2", 16, 64, 115, 41)
GUISetState(@SW_SHOW)


Global $hGUI = GUICreate("", 800, 600, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME))
GUISetBkColor(0x000000)
GUISetOnEvent($hGUI, "SpecialEvents2")
Global $idPic = GUICtrlCreatePic("", 0, 0, 100, 100)
GUISetState(@SW_HIDE, $hGUI)

GUIRegisterMsg($WM_SIZE, WM_SIZE)

While True
    Sleep(10)
WEnd

Func _Start()
    Global $hImage = _GDIPlus_ImageLoadFromFile("C:\Users\Windows 10 Pro\Desktop\Test\Images\2.jpg")
    Global $iImageWidth = _GDIPlus_ImageGetWidth($hImage), $iImageHeight = _GDIPlus_ImageGetHeight($hImage)
    Local $aPos[] = [$iImageWidth, $iImageHeight]
    If $iImageWidth > @DesktopWidth Or $iImageHeight > @DesktopHeight Then
        $aPos = _EvaluateSize(@DesktopWidth, @DesktopHeight, $iImageWidth, $iImageHeight)
    EndIf
    Global $hBitMap = _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])
    GUISetState(@SW_SHOW, $hGUI)
EndFunc   ;==>_Start


Func _EvaluateSize($iBaseWidth, $iBaseHeight, $iActualWidth, $iActualHeight)
    Local $iVal = $iBaseWidth / $iActualWidth * $iActualHeight
    If $iVal <= $iBaseHeight Then Return StringSplit($iBaseWidth & "|" & $iVal, "|", $STR_NOCOUNT)
    $iVal = $iBaseHeight / $iActualHeight * $iActualWidth
    Return StringSplit($iVal & "|" & $iBaseHeight, "|", $STR_NOCOUNT)
EndFunc   ;==>_EvaluateSize

Func _SetImagetoCtrl($idPic, $hImage, $iWidth, $iHeight)
    Local $hResize = _GDIPlus_ImageResize($hImage, $iWidth, $iHeight)
    Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hResize)
    _GDIPlus_ImageDispose($hResize)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap))
    Return $hHBitmap
EndFunc   ;==>_SetImagetoCtrl

Func WM_SIZE($hWnd, $nMsg, $wParam, $lParam)
    AdlibRegister(_ResizeImage, 5)
    Return 1
EndFunc   ;==>WM_SIZE

Func _ResizeImage()
    AdlibUnRegister(_ResizeImage)
    Local $tRECT = _WinAPI_GetClientRect($hGUI)
    Local $iWidth = $tRECT.right - $tRECT.left + 1
    Local $iHeight = $tRECT.bottom - $tRECT.top + 1
    If $iWidth > $iImageWidth And $iHeight > $iImageHeight Then
        Local $aPos[] = [$iImageWidth, $iImageHeight]
    Else
        Local $aPos = _EvaluateSize($iWidth, $iHeight, $iImageWidth, $iImageHeight)
    EndIf
    _WinAPI_MoveWindow(GUICtrlGetHandle($idPic), Int(($iWidth - $aPos[0]) / 2), Int(($iHeight - $aPos[1]) / 2), $aPos[0], $aPos[1])
    $hBitMap = _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])
EndFunc   ;==>_ResizeImage

Func SpecialEvents()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            Exit
        Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
        Case @GUI_CtrlId = $GUI_EVENT_RESTORE
    EndSelect
EndFunc   ;==>SpecialEvents

Func SpecialEvents2()
    Select
        Case @GUI_CtrlId = $GUI_EVENT_CLOSE
            GUISetState(@SW_HIDE, $hGUI)
            GUISetState(@SW_SHOW, $Form1)
        Case @GUI_CtrlId = $GUI_EVENT_MINIMIZE
        Case @GUI_CtrlId = $GUI_EVENT_RESTORE
    EndSelect
EndFunc   ;==>SpecialEvents2

 

Edited by beginner10
Link to comment
Share on other sites

There is a large memory leak in the code I gave you.  Please take this latest version of the code :

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPISysWin.au3>

_GDIPlus_Startup()

Example()

_GDIPlus_Shutdown()

Func Example()
  Local Const $BASE_WIDTH = 800, $BASE_HEIGHT = 600
  Global $hImage = _GDIPlus_ImageLoadFromFile("Image.jpg")
  Global $iImageWidth = _GDIPlus_ImageGetWidth($hImage), $iImageHeight = _GDIPlus_ImageGetHeight($hImage)
  Local $aPos[] = [$iImageWidth, $iImageHeight]

  If $iImageWidth > $BASE_WIDTH Or $iImageHeight > $BASE_HEIGHT Then
    $aPos = _EvaluateSize($BASE_WIDTH, $BASE_HEIGHT, $iImageWidth, $iImageHeight)
  EndIf

  Global $hGUI = GUICreate("", $aPos[0], $aPos[1], -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME))
  GUISetBkColor(0x000000)
  Global $idPic = GUICtrlCreatePic("", 0, 0, $aPos[0], $aPos[1])
  _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])

  GUIRegisterMsg($WM_SIZE, WM_SIZE)

  GUISetState()
  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd
EndFunc   ;==>Example

Func _EvaluateSize($iBaseWidth, $iBaseHeight, $iActualWidth, $iActualHeight)
  Local $iVal = $iBaseWidth / $iActualWidth * $iActualHeight
  If $iVal <= $iBaseHeight Then Return StringSplit($iBaseWidth & "|" & $iVal, "|", $STR_NOCOUNT)
  $iVal = $iBaseHeight / $iActualHeight * $iActualWidth
  Return StringSplit($iVal & "|" & $iBaseHeight, "|", $STR_NOCOUNT)
EndFunc   ;==>_EvaluateSize

Func _SetImagetoCtrl($idPic, $hImage, $iWidth, $iHeight)
  Local $hResize = _GDIPlus_ImageResize($hImage, $iWidth, $iHeight)
  Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hResize)
  _GDIPlus_ImageDispose($hResize)
  _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap))
  _WinAPI_DeleteObject($hHBitmap)
EndFunc   ;==>_SetImagetoCtrl

Func WM_SIZE($hWnd, $nMsg, $wParam, $lParam)
  AdlibRegister(_ResizeImage, 5)
  Return 1
EndFunc   ;==>WM_SIZE

Func _ResizeImage()
  AdlibUnRegister(_ResizeImage)
  Local $tRECT = _WinAPI_GetClientRect($hGUI)
  Local $iWidth = $tRECT.right - $tRECT.left + 1
  Local $iHeight = $tRECT.bottom - $tRECT.top + 1
  If $iWidth > $iImageWidth And $iHeight > $iImageHeight Then
    Local $aPos [] = [$iImageWidth, $iImageHeight]
  Else
    Local $aPos = _EvaluateSize($iWidth, $iHeight, $iImageWidth, $iImageHeight)
  EndIf
  _WinAPI_MoveWindow(GUICtrlGetHandle($idPic), Int(($iWidth-$aPos[0])/2), Int(($iHeight-$aPos[1])/2), $aPos[0], $aPos[1])
  _SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])
EndFunc   ;==>_ResizeImage

 

Edited by Nine
Link to comment
Share on other sites

@Aelc and @beginner10.  I tested with a large image (3.2k x 1.8k) and there is effectively a tad more lag.  One solution I found is to resize the base image to fit screen dimensions.  It helps for sure.

Func _ReduceLargeImage (ByRef $hImage, ByRef $iImageWidth, ByRef $iImageHeight)
  If $iImageWidth <= @DesktopWidth Or $iImageHeight <= @DesktopHeight Then Return
  Local $aPos = _EvaluateSize(@DesktopWidth, @DesktopHeight, $iImageWidth, $iImageHeight)
  Local $hResize = _GDIPlus_ImageResize($hImage, $aPos[0], $aPos[1])
  _GDIPlus_ImageDispose($hImage)
  $hImage = $hResize
  $iImageWidth = $aPos[0]
  $iImageHeight = $aPos[1]
EndFunc

Use this function in main :

Local Const $BASE_WIDTH = 800, $BASE_HEIGHT = 600
  Global $hImage = _GDIPlus_ImageLoadFromFile("Image.jpg")
  Global $iImageWidth = _GDIPlus_ImageGetWidth($hImage), $iImageHeight = _GDIPlus_ImageGetHeight($hImage)
  _ReduceLargeImage ($hImage, $iImageWidth, $iImageHeight)
  Local $aPos[] = [$iImageWidth, $iImageHeight]

.....

 

Link to comment
Share on other sites

well still without WM_SIZE, it doesn't flicker that much. :P  or are there problems to simply use GuiCtrlSetPos()?

a mix from both that works well for me ( win7 64-bit )

 

nevermind i got the problem with bigger pictures :D 

 

but it works if the Base Stats are at desktopsize :sorcerer:

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <WinAPISysWin.au3>
_GDIPlus_Startup()
Local Const $BASE_WIDTH = @DesktopWidth, $BASE_HEIGHT = @DesktopHeight - 65
Global $hImage = _GDIPlus_ImageLoadFromFile("Image.jpg")
Global $iImageWidth = _GDIPlus_ImageGetWidth($hImage), $iImageHeight = _GDIPlus_ImageGetHeight($hImage)
_ReduceLargeImage($hImage, $iImageWidth, $iImageHeight)
Local $aPos[] = [$iImageWidth, $iImageHeight]
If $iImageWidth > $BASE_WIDTH Or $iImageHeight > $BASE_HEIGHT Then
    $aPos = _EvaluateSize($BASE_WIDTH, $BASE_HEIGHT, $iImageWidth, $iImageHeight)
EndIf

Global $hGUI = GUICreate("", $aPos[0], $aPos[1], -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME))
GUISetBkColor(0x000000)
Global $idPic = GUICtrlCreatePic("", 0, 0, $aPos[0], $aPos[1])
_SetImagetoCtrl($idPic, $hImage, $aPos[0], $aPos[1])
AdlibRegister("_ResizeImage", 5)
GUISetState()

While 1
    Local $nMsg = GUIGetMsg()
    Switch $nMsg
        Case -3
            Exit
    EndSwitch
WEnd

Func _ReduceLargeImage(ByRef $hImage, ByRef $iImageWidth, ByRef $iImageHeight)
    If $iImageWidth <= @DesktopWidth Or $iImageHeight <= @DesktopHeight Then Return
    Local $aPos = _EvaluateSize(@DesktopWidth, @DesktopHeight, $iImageWidth, $iImageHeight)
    Local $hResize = _GDIPlus_ImageResize($hImage, $aPos[0], $aPos[1])
    _GDIPlus_ImageDispose($hImage)
    $hImage = $hResize
    $iImageWidth = $aPos[0]
    $iImageHeight = $aPos[1]
EndFunc   ;==>_ReduceLargeImage

Func _EvaluateSize($iBaseWidth, $iBaseHeight, $iActualWidth, $iActualHeight)
    Local $iVal = $iBaseWidth / $iActualWidth * $iActualHeight
    If $iVal <= $iBaseHeight Then Return StringSplit($iBaseWidth & "|" & $iVal, "|", $STR_NOCOUNT)
    $iVal = $iBaseHeight / $iActualHeight * $iActualWidth
    Return StringSplit($iVal & "|" & $iBaseHeight, "|", $STR_NOCOUNT)
EndFunc   ;==>_EvaluateSize

Func _SetImagetoCtrl($idPic, $hImage, $iWidth, $iHeight)
    Local $hResize = _GDIPlus_ImageResize($hImage, $iWidth, $iHeight)
    Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hResize)
    _GDIPlus_ImageDispose($hResize)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap))
    _WinAPI_DeleteObject($hHBitmap)
EndFunc   ;==>_SetImagetoCtrl

Func _ResizeImage()
    Local $tRECT = _WinAPI_GetClientRect($hGUI)
    Local $iWidth = $tRECT.right - $tRECT.left + 1
    Local $iHeight = $tRECT.bottom - $tRECT.top + 1
    If $iWidth > $iImageWidth And $iHeight > $iImageHeight Then
        Local $aPos[] = [$iImageWidth, $iImageHeight]
    Else
        Local $aPos = _EvaluateSize($iWidth, $iHeight, $iImageWidth, $iImageHeight)
    EndIf
    Local $aIMGpos = ControlGetPos($hGUI, "", $idPic)
    If $aIMGpos[0] <> Int(($iWidth - $aPos[0]) / 2) Or $aIMGpos[1] <> Int(($iHeight - $aPos[1]) / 2) Or Int($aPos[0]) <> $aIMGpos[2] Or Int($aPos[1]) <> $aIMGpos[3] Then GUICtrlSetPos($idPic, Int(($iWidth - $aPos[0]) / 2), Int(($iHeight - $aPos[1]) / 2), $aPos[0], $aPos[1])
EndFunc   ;==>_ResizeImage

 

Edited by Aelc

why do i get garbage when i buy garbage bags? <_<

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