Jump to content
Sign in to follow this  
Zoldex

GUICtrlCreatePic strange behaviour

Recommended Posts

Zoldex

I'm trying to displaya picture on a gui but it doesn't work if I make some GDI+ operations just before creating the gui:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <ScreenCapture.au3>
#Include <Misc.au3>
#include <StaticConstants.au3>

Local $GUIimg_title,$GUIwidth,$GUIheight,$GUILeft,$GUITop

Local $filename = FileOpenDialog("Select image", @ScriptDir, "Image (*.jpg;*.bmp)", 3)

_GDIPlus_Startup()

Local $imagefromfile = _GDIPlus_ImageLoadFromFile($filename) ;Create an image object based on a file
Local $GUIwidth = _GDIPlus_ImageGetWidth($imagefromfile)
Local $GUIheight = _GDIPlus_ImageGetHeight($imagefromfile)


; Display image
$hBitmap_GUI = GUICreate("", $GUIwidth, $GUIheight)
$hPic = GUICtrlCreatePic($filename, 0, 0)

GUISetState()
_GDIPlus_Shutdown()


While 1

Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE;, $hCancel_Button
Exit
;~
EndSwitch

WEnd

Instead it works if I remove GDI+ ... Can't understand why!

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <ScreenCapture.au3>
#Include <Misc.au3>
#include <StaticConstants.au3>
Local $GUIimg_title,$GUIwidth,$GUIheight,$GUILeft,$GUITop

Local $filename = FileOpenDialog("Select image", @ScriptDir, "Image (*.jpg;*.bmp)", 3)

;~ _GDIPlus_Startup()

;~ Local $imagefromfile = _GDIPlus_ImageLoadFromFile($filename) ;Create an image object based on a file
;~ Local $GUIwidth = _GDIPlus_ImageGetWidth($imagefromfile)
;~ Local $GUIheight = _GDIPlus_ImageGetHeight($imagefromfile)
;~ _GDIPlus_Shutdown()


; Display image
;$hBitmap_GUI = GUICreate("", $GUIwidth, $GUIheight)
$hBitmap_GUI = GUICreate("", 800, 800); <---- had to use fixed size...
$hPic = GUICtrlCreatePic($filename, 1, 1)

GUISetState()


While 1

Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE;, $hCancel_Button
Exit
;~
EndSwitch

WEnd

:huh2:

Any hints?

Edited by Zoldex

Share this post


Link to post
Share on other sites
BrewManNH

Not sure why the GDI+ stuff is causing a problem, but if all you need it for is to get the dimensions of the file, you could do it this way.

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <Array.au3>
Local $GUIimg_title, $GUIwidth, $GUIheight, $GUILeft, $GUITop

Local $filename = FileOpenDialog("Select image", @ScriptDir, "Image (*.jpg;*.bmp)", 3)

;~ _GDIPlus_Startup()

;~ Local $imagefromfile = _GDIPlus_ImageLoadFromFile($filename) ;Create an image object based on a file
;~ Local $GUIwidth = _GDIPlus_ImageGetWidth($imagefromfile)
;~ Local $GUIheight = _GDIPlus_ImageGetHeight($imagefromfile)

;~ _GDIPlus_Shutdown()

; Display image
$aDimensions = StringRegExp(_FileGetProperty($filename, "height"), "(d+)", 2)
$GUIheight = $aDimensions[0]
$aDimensions = StringRegExp(_FileGetProperty($filename, "width"), "(d+)", 2)
$GUIwidth = $aDimensions[0]
$hBitmap_GUI = GUICreate("", $GUIwidth, $GUIheight)
$hPic = GUICtrlCreatePic($filename, 0, 0, 0, 0)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE;, $hCancel_Button
            Exit

    EndSwitch

WEnd
;===============================================================================
; Function Name.....: _FileGetProperty
; Description.......: Returns a property or all properties for a file.
; Version...........: 1.0.2
; Change Date.......: 05-16-2012
; AutoIt Version....: 3.2.12.1+
; Parameter(s)......: $S_PATH - String containing the file path to return the property from.
;                     $S_PROPERTY - [optional] String containing the name of the property to return. (default = "")
; Requirements(s)...: None
; Return Value(s)...: Success: Returns a string containing the property value.
;                       If $S_PROPERTY is empty, an two-dimensional array is returned:
;                         $av_array[0][0] = Number of properties.
;                         $av_array[1][0] = 1st property name.
;                         $as_array[1][1] = 1st property value.
;                         $av_array[n][0] = nth property name.
;                         $as_array[n][1] = nth property value.
;                     Failure: Returns 0 and sets @error to:
;                       1 = The folder $S_PATH does not exist.
;                       2 = The property $S_PROPERTY does not exist or the array could not be created.
;                       3 = Unable to create the "Shell.Application" object $objShell.
; Author(s).........: - Simucal <Simucal@gmail.com>
;                     - Modified by: Sean Hart <autoit@hartmail.ca>
;                     - Modified by: teh_hahn <sPiTsHiT@gmx.de>
;                     - Modified by: BrewManNH
; URL...............: http://www.autoitscript.com/forum/topic/34732-udf-getfileproperty/page__view__findpost__p__557571
; Note(s)...........: Modified the script that teh_hahn posted at the above link to include the properties that
;                     Vista and Win 7 include that Windows XP doesn't. Also removed the ReDims for the $av_ret array and
;                     replaced it with a single ReDim after it has found all the properties, this should speed things up.
;===============================================================================
Func _FileGetProperty($S_PATH, Const $S_PROPERTY = "")
    $S_PATH = StringRegExpReplace($S_PATH, '["'']', "") ; strip the quotes, if any from the incoming string
    If Not FileExists($S_PATH) Then Return SetError(1, 0, 0)
    Local Const $objShell = ObjCreate("Shell.Application")
    If @error Then Return SetError(3, 0, 0)
    Local $iPropertyCount = 300 ; arbitrary number used, Windows 7 only returns 289 properties, Windows XP only returns 38 (future proofing)
    Local Const $S_FILE = StringTrimLeft($S_PATH, StringInStr($S_PATH, "", 0, -1))
    Local Const $S_DIR = StringTrimRight($S_PATH, StringLen($S_FILE) + 1)
    Local Const $objFolder = $objShell.NameSpace($S_DIR)
    Local Const $objFolderItem = $objFolder.Parsename($S_FILE)
    If $S_PROPERTY Then
        For $I = -1 To $iPropertyCount + 1
            If $objFolder.GetDetailsOf($objFolder.Items, $I) = $S_PROPERTY Then
                Return $objFolder.GetDetailsOf($objFolderItem, $I)
            EndIf
        Next
        Return SetError(2, 0, 0)
    EndIf
    Local $av_ret[$iPropertyCount][2] = [[1]]
    For $I = 1 To $iPropertyCount + 1
        If $objFolder.GetDetailsOf($objFolder.Items, $I) Then
            $av_ret[$I][0] = $objFolder.GetDetailsOf($objFolder.Items, $I - 1)
            $av_ret[$I][1] = $objFolder.GetDetailsOf($objFolderItem, $I - 1)
            $av_ret[0][0] += 1
        EndIf
    Next
    ReDim $av_ret[$av_ret[0][0] + 1][2]
    If Not $av_ret[1][0] Then Return SetError(2, 0, 0)
    Return $av_ret
EndFunc   ;==>_FileGetProperty

I used the RegEx because the results on my computer returns ### pixels, where the ### is the dimension size and this will strip off anything not a number.

This works on Windows 7, XP does not have this information available, but does have the Dimensions property you could work with.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
Andreik

It's because you do not dispose the image and is still in use. Try this:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <ScreenCapture.au3>
#Include <Misc.au3>
#include <StaticConstants.au3>

Local $GUIimg_title,$GUIwidth,$GUIheight,$GUILeft,$GUITop

Local $filename = FileOpenDialog("Select image", @ScriptDir, "Image (*.jpg;*.bmp)", 3)

_GDIPlus_Startup()

Local $imagefromfile = _GDIPlus_ImageLoadFromFile($filename) ;Create an image object based on a file
Local $GUIwidth = _GDIPlus_ImageGetWidth($imagefromfile)
Local $GUIheight = _GDIPlus_ImageGetHeight($imagefromfile)
_GDIPlus_ImageDispose($imagefromfile)
_GDIPlus_Shutdown()

; Display image
$hBitmap_GUI = GUICreate("", $GUIwidth, $GUIheight)
$hPic = GUICtrlCreatePic($filename, 0, 0, $GUIwidth, $GUIheight)

GUISetState()



While 1

Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE;, $hCancel_Button
Exit
;~
EndSwitch

WEnd
  • Like 1

When the words fail... music speaks

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  

  • Similar Content

    • c.haslam
      By c.haslam
      I think that this UDF should return a Property Item that can readily be set as a property of another image. Why would one want to do this? A script might (as one of mine does) edit an image of a .jpg file then write the result to a .jpg file. In editing it, in my case, the number of horizontal and vertical pixels change, and the date/time edited should be set as a property. All other property items remain the same. Other GDI+ users may change other properties.
      So an approach is to copy all the property items from image1 to image2, then update a few properties.
      M$ provides a Property Item class (id, length, pointer to an array of values) but _GDIPlus_ImageGetPropertyItem returns something different.
      I think that, wherever reasonable, UDFs that are wrappers for M$ methods should work like M$'s methods. _GDIPlus_ImageGetPropertyItem does not do this:
      There is a bug in _GDIPlus_ImageGetPropertyItem: the Case Else should have $iValues = $iBytes not $iValues = 1 While M$ returns 2 values for a value that is a ratio of 2 numbers,  _GDIPlus_ImageGetPropertyItem returns numerator/denominator as a single value (often a Double). _GDIPlus_ImageSetPropertyItem (when included in GDIPlus.au3) will be unable to set ratio property items properly because it cannot know what the numerator and denominator are. So copying such property items will not work properly. M$ has a Void* buffer where the buffer is an array of values but _GDIPlus_ImageGetPropertyItem() returns the values in the same 1-d array as id, length and type. M$'s approach produces a 1-d array with the same number of elements for all property items while _GDIPlus_ImageGetPropertyItem produces a 1-d array with various numbers of elements. To me, this is not good programming practice. For a photo from a Sony camera, the worst case has 1-d array with 67 elements. When combined into a 2-d array with the property items of all properties, there are 66 rows and 67 columns, with many elements not used. So I suggest that _GDIPlus_ImageGetPropertyItem look like this:
      ; #FUNCTION# ==================================================================================================================== ; Name ..........: cGDIPlus_ImageGetPropertyItem ; Description ...: Gets a specified property item (piece of meta data) from an Image object ; Syntax ........: cGDIPlus_ImageGetPropertyItem($hImage, $iPropID) ; Parameters ....: $hImage - Pointer to an image object ; $iPropID - Identifier of the property item to be retrieved ; Return values .: Success: Array containing the values of the property item ; [0] - identifier ; [1] - size, in bytes, of the value array ; [2] - type of value(s) in the value array ; [3] - value array ; Failure: Sets the @error flag to non-zero, @extended may contain GPSTATUS error code ($GPID_ERR*). ; Author ........: Eukalyptus ; Modified ......: c.haslam ; Remarks .......: types: unsigned byte = 1, ASCII string = 2, unsigned short = 3, unsigned long = 4, ; unsinged rational = 5, signed byte = 6, undefined = 7, signed long = 9, ; signed rational = 10 ; Related .......: _GDIPlus_ImageGetPropertyIdList ; Link ..........: https://msdn.microsoft.com/en-us/library/windows/desktop/ms535390(v=vs.85).aspx, ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms534493(v=vs.85).aspx, ; https://msdn.microsoft.com/en-us/library/windows/desktop/ms534414(v=vs.85).aspx ; Example .......: Yes ; =============================================================================================================================== Func cGDIPlus_ImageGetPropertyItem($hImage, $iPropID) Local $iSize = __GDIPlus_ImageGetPropertyItemSize($hImage, $iPropID) If @error Then Return SetError(@error, @extended, -1) Local $tBuffer = DllStructCreate("byte[" & $iSize & "];") Local $pBuffer = DllStructGetPtr($tBuffer) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetPropertyItem", "handle", $hImage, "uint", _ $iPropID, "uint", $iSize, "struct*", $tBuffer) If @error Then Return SetError(@error, @extended, -1) If $aResult[0] Then Return SetError(10, $aResult[0], False) Local $tPropertyItem = DllStructCreate("int id; int length; short type; ptr value;", $pBuffer) Local $iBytes = DllStructGetData($tPropertyItem, "length") Local $pValue = DllStructGetData($tPropertyItem, "value") Local $aRet[4] Local $type = DllStructGetData($tPropertyItem,'type') Local $tValues, $iValues Switch $type Case 2 ;ASCII String $iValues = 1 $tValues = DllStructCreate("char[" & $iBytes & "];", $pValue) Case 3 ;Array of UShort $iValues = Int($iBytes / 2) $tValues = DllStructCreate("ushort[" & $iValues & "];", $pValue) Case 4, 5 ;Array of UInt / Fraction $iValues = Int($iBytes / 4) $tValues = DllStructCreate("uint[" & $iValues & "];", $pValue) Case 9, 10 ;Array of Int / Fraction $iValues = Int($iBytes / 4) $tValues = DllStructCreate("int[" & $iValues & "];", $pValue) Case Else ;Array of Bytes $iValues = $iBytes $tValues = DllStructCreate("byte[" & $iBytes & "];", $pValue) EndSwitch $aRet[0] = DllStructGetData($tPropertyItem,'id') $aRet[1] = $iBytes $aRet[2] = $type Local $aVals[$iValues] If $type=2 Or $type=7 Then ; ASCII string or undefined $aVals[0] = DllStructGetData($tValues,1) Else For $i = 0 To $iValues-1 $aVals[$i] = DllStructGetData($tValues,1,$i+1) Next EndIf $aRet[3] = $aVals Return $aRet EndFunc And here is an example:
      #include <GDIPlus.au3> #include <Array.au3> Example() Func Example() _GDIPlus_Startup() Local $hImage = _GDIPlus_ImageLoadFromFile(RegRead((@AutoItX64 = True ? "HKLM\SOFTWARE\Wow6432Node\AutoIt v3\AutoIt" : "HKLM\SOFTWARE\AutoIt v3\AutoIt"), "InstallDir") & "\Examples\GUI\Torus.png") If @error Then _GDIPlus_Shutdown() MsgBox(16, "", "An error has occured - unable to load image!", 30) Return False EndIf Local $ar = _GDIPlus_ImageGetPropertyIdList($hImage) Local $vPropNbrs[UBound($ar,1)-1] ; Extract ID numbers For $i = 1 To UBound($ar,1)-1 $vPropNbrs[$i-1] = $ar[$i][0] Next ; Get all property items Local $aPropItems[UBound($vPropNbrs)][4],$vPropItem For $i = 0 To UBound($vPropNbrs)-1 $vPropItem = cGDIPlus_ImageGetPropertyItem($hImage,$vPropNbrs[$i]) For $j = 0 To 3 $aPropItems[$i][$j] = $vPropItem[$j] Next Next ; Collapse values arrays so _ArrayDisplay can display them Local $ar = $aPropItems For $i = 0 To UBound($aPropItems,1)-1 $ar[$i][0] = '0x'&Hex($ar[$i][0],4) $ar[$i][3] = '' For $j = 0 To UBound($aPropItems[$i][3])-1 $ar[$i][3] &= ($aPropItems[$i][3])[$j]&'|' Next $ar[$i][3] = StringTrimRight($ar[$i][3],1) Next _ArrayDisplay($ar) _GDIPlus_Shutdown() EndFunc Unfortunately this example (based on one now the Help) does not exercise most of the item types, but I do not know of a file with EXIF metadata that is on most PCs. The code for implementing and calling _GDIPlus_ImageSetPropertyItem will be fairly simple.
       
      Your thoughts?
       
    • c.haslam
      By c.haslam
      I have a strange symptom of a problem somewhere in my code, or in a UDF: when I add code to get all properties of a GDI+ image to a 6000-line script,  the variable type of a parameter is reported as a pointer when the caller clearly has this argument as a string. If I comment out my code that gets the properties, the function properly sees the parameter as a string.
      [Edit: The reporting as a pointer and getting image properties are miles apart, both in where they are in the script code and in where they are run.]
      At this point, I am looking for clues as to why this is happening, so the hunt is on!
      I have noticed one odd thing, in _GDIPlus_ImageGetPropertyIdList() I see a line that begins Local $sPropertyTagInfo = . This "line" is split into 2 lines. SCiTE shows that the first line is 2454 characters and the second 2400. Adding these numbers I get 4854 characters.
      But the Help for AutoIt3 Limits/defaults says that MAXLINESIZE, Maximum size for a line of script, is 4096 characters.
      The line would exceed the limit if AutoIt considers the subject line to be 1 line and not 2 lines.
      My question: is this line legal? Is buffer overun possible?
    • c.haslam
      By c.haslam
      I find _GDIPlus_ImageClone in the Help, but neither in SciTe auto-complete nor in GDIPlus.au3
      Shoud this be reported in Trac?
      By searching the forum (and changing the name of the first arguement ot DLLCall, the code appears to be:
      Func _GDIPlus_ImageClone($hImage) Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipCloneImage", "handle", $hImage, "int*", 0) If @error Then Return SetError(@error, @extended, 0) Return $aResult[2] EndFunc ;==>_GDIPlus_ImageClone  
    • TheAutomator
      By TheAutomator
      Is this better to check a variable before you assign it to a value that could be the same?
      for example:
      local $EmptyLog = false func WriteLog($text) _guictrledit_appendtext($log, ($EmptyLog ? @CRLF : $empty) & $text) If $EmptyLog Then $EmptyLog = False endfunc or does AutoIt behind the scenes already check this?
      i guess overwriting memory with the same value over and over again is not good if you can prevent this with a check?
    • JNutt
      By JNutt
      I see $hWnd used as a local variable in a lot of script examples.  I know the 'h' is used for handles, but what is the 'Wnd' short for?
      Thanks!
×

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.