Champak Posted June 8, 2023 Posted June 8, 2023 I'm using GUICtrlCreatePic to show an image....it's a simple gui with only that control and it takes up the whole gui. It's many different images that can show...different sizes. In order to make sure the whole image shows I of course set the size portion of GUICtrlCreatePic. My issue is I am not happy with the way some pics are displayed from simply setting the image size. Many look squashed. Is there a way to simply scale the image (quickly) to fit the size of the gui vs putting a fixed value that may go against the aspect ratio and stretches or squashes the image?
Musashi Posted June 8, 2023 Posted June 8, 2023 1 hour ago, Champak said: Is there a way to simply scale the image (quickly) to fit the size of the gui vs putting a fixed value that may go against the aspect ratio and stretches or squashes the image? In order for an image to cover the entire GUI without loss, i.e. without cutting off picture content, both must have an identical aspect ratio. Otherwise, distortions will inevitably occur. You probably know this effect when, for example, movies are displayed on a TV with different scaling. This causes right and left parts of the movie to be clipped and/or black bars. "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."
Champak Posted June 8, 2023 Author Posted June 8, 2023 (edited) Right, but I was looking for a solution like photo editing software where you put in either the width OR the length and the other is automatically scaled to keep the proper ratio. I was hoping there was a way to do that here to remedy this issue. EDIT: It occurred to me this may be possible. 1/ Get the image size 2/ Determine which of width or height is larger and work with that. 3/ Calculate percentage reduction to get to the width or height of the gui 4/ Apply that percentage reduction to the "other side" width/height This should maintain the aspect ratio and have the image fit "perfectly" within the gui, no squishing/expansion. Does this sound right to work? It's late and my mind is not working right now and the formula is not coming to me. If there is another way...or this wont work...let me know. Edited June 8, 2023 by Champak
Shark007 Posted June 8, 2023 Posted June 8, 2023 (edited) here is something I've borrowed from @UEZ #include <GDIPlus.au3> _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\Torus.png") Local $iScale = "your scaling factor here" Local $B_Scaled = _GDIPlus_ImageScale($hImage, $iScale, $iScale) Local $idPic = GUICtrlCreatePic("", 196, 82, _GDIPlus_ImageGetWidth($B_Scaled), _GDIPlus_ImageGetHeight($B_Scaled)) GUICtrlSendMsg($idPic, 0x0172, 0, _GDIPlus_BitmapCreateHBITMAPFromBitmap($B_Scaled)) _GDIPlus_BitmapDispose($B_Scaled) _GDIPlus_Shutdown() Edited June 8, 2023 by Shark007
UEZ Posted June 8, 2023 Posted June 8, 2023 Might help you: Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
Champak Posted June 8, 2023 Author Posted June 8, 2023 (edited) This is what I came up with, if there is a better way let me know. expandcollapse popup#include <GDIPlus.au3> #include <GUIConstantsEx.au3> Example() Func Example() _GDIPlus_Startup() Local Const $iW = 400, $iH = 400 Global $WidthP = False, $HeightP = False $hBitmap = _GDIPlus_ImageLoadFromFile("image") ; Get the size of the original $iX1 = _GDIPlus_ImageGetWidth($hBitmap) $iY1 = _GDIPlus_ImageGetHeight($hBitmap) If $iX1 > $iY1 Then $Prime = $iX1 $WidthP = True Else $Prime = $iY1 $HeightP = True EndIf ; Calculate percentage decrease $x = ($Prime - 400) / $Prime $x = $x * 100 $x = 100 - $x $x = $x/100 ; Set percentage change Local $iScale = $x;1.0 is without any scaling Local $hBitmap_Scaled = _GDIPlus_ImageScale($hBitmap, $iScale, $iScale, $GDIP_INTERPOLATIONMODE_NEARESTNEIGHBOR) ;scale image by 275% (magnify) ; Get the width of new $iX1 = _GDIPlus_ImageGetWidth($hBitmap_Scaled) $iY1 = _GDIPlus_ImageGetHeight($hBitmap_Scaled) If $WidthP = True Then $adjustedY = (400 - $iY1) / 2 $adjustedx = 0 Else $adjustedX = (400 - $iX1) / 2 $adjustedY = 0 EndIf Local $hGUI = GUICreate("GDI+ test", $iW, $iH, -1, -1) ;create a test gui to display the resized image GUISetState(@SW_SHOW) Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap_Scaled, $adjustedX, $adjustedY) ;display scaled image While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ;cleanup resources _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_BitmapDispose($hBitmap_Scaled) _GDIPlus_Shutdown() GUIDelete($hGUI) EndFunc ;==>Example Edited June 8, 2023 by Champak
Andreik Posted June 8, 2023 Posted June 8, 2023 (edited) I made an example with different modes of fitting an image to a container. It's CSS like object-fit property: expandcollapse popup#include <GDIPlus.au3> #include <WinAPI.au3> Global $hMain, $cPic Global $aFitObject = ['Fill', 'Contain', 'Cover'] $hMain = GUICreate('Sample GUI', 400, 400) GUISetState(@SW_SHOW, $hMain) For $Mode = 0 To 2 $cPic = GUICtrlCreatePic('', 0, 0, 400, 400) SetImage('image.jpg', $cPic, $aFitObject[$Mode]) Sleep(3000) GUICtrlDelete($cPic) Next Func SetImage($sImage, $cCtrl, $sFitType) If Not FileExists($sImage) Then Return Local $aPos = ControlGetPos($hMain, '', $cCtrl) _GDIPlus_Startup() Local $hResizedImage = Null, $hContext = Null Local $hImage = _GDIPlus_ImageLoadFromFile($sImage) If @error Then _GDIPlus_Shutdown() Return EndIf Local $aDim = _GDIPlus_ImageGetDimension($hImage) Local $iRW = $aPos[2] / $aDim[0] Local $iRH = $aPos[3] / $aDim[1] Switch $sFitType Case 'Contain' Local $iSR = ($iRW < $iRH ? $iRW : $iRH) Local $iX = Int(($aPos[2] - ($aDim[0] * $iSR)) / 2) Local $iY = Int(($aPos[3] - ($aDim[1] * $iSR)) / 2) $hResizedImage = _GDIPlus_BitmapCreateFromScan0($aPos[2], $aPos[3]) $hContext = _GDIPlus_ImageGetGraphicsContext($hResizedImage) _GDIPlus_GraphicsDrawImageRectRect($hContext, $hImage, 0, 0, $aDim[0], $aDim[1], $iX, $iY, $aDim[0] * $iSR, $aDim[1] * $iSR) Case 'Cover' Local $iLR = ($iRW > $iRH ? $iRW : $iRH) Local $iX = Int(($aPos[2] - ($aDim[0] * $iLR)) / 2) Local $iY = Int(($aPos[3] - ($aDim[1] * $iLR)) / 2) $hResizedImage = _GDIPlus_BitmapCreateFromScan0($aPos[2], $aPos[3]) $hContext = _GDIPlus_ImageGetGraphicsContext($hResizedImage) _GDIPlus_GraphicsDrawImageRectRect($hContext, $hImage, 0, 0, $aDim[0], $aDim[1], $iX, $iY, $aDim[0] * $iLR, $aDim[1] * $iLR) Case 'Fill' $hResizedImage = _GDIPlus_BitmapCreateFromScan0($aPos[2], $aPos[3]) $hContext = _GDIPlus_ImageGetGraphicsContext($hResizedImage) _GDIPlus_GraphicsDrawImageRectRect($hContext, $hImage, 0, 0, $aDim[0], $aDim[1], 0, 0, $aDim[0] * $iRW, $aDim[1] * $iRH) EndSwitch If $hResizedImage <> Null Then Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hResizedImage) _WinAPI_DeleteObject(GUICtrlSendMsg($cCtrl, 0x0172, 0, $hHBITMAP)) _WinAPI_DeleteObject($hHBITMAP) EndIf If $hContext <> Null Then _GDIPlus_GraphicsDispose($hContext) If $hResizedImage <> Null Then _GDIPlus_BitmapDispose($hResizedImage) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() EndFunc Edited August 22, 2024 by Andreik
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now