Jump to content

Get Image Location


Recommended Posts

Is there a way to check if the image is currently load from the given file path that was assigned?

 

ex:

if guictrlsetimage($img, @scriptdir & "\test.jpg") = @scriptdir & "\test.jpg" then
;do code
endif

 

Msgbox(0, "Hate", "Just hate it when I post a question and find my own answer after a couple tries. But if I don't post the question, I can't seem to resolve it at all.")
Link to comment
Share on other sites

I don't think I've ever seen a function to get the image location. Fortunately I was working with some HBitmaps last night trying to compare them. So after messing around with it and extracting the HBitmap from the pic control we can compare the two images. The only thing is, if the Image Control (GUICtrlCreatePic) are not the exact width and height of the image, then the compare is going to fail. The reason it's going to fail is because Windows will resize the image to fit the control, and once it does that then the pics (bytes of memory) of the image are going to be affected. In my tests no two resized images have the same bytes, understandably. So in order for you to compare your two images the image control needs to be the same width and height as the image you use for it.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <WinApi.au3>
#include <StaticConstants.au3>
#include <InetConstants.au3>

DownloadImage("https://www.autoitscript.com/autoit3/files/graphics/autoit_metal_wall_800x600.jpg", @ScriptDir & "\Image.jpg")
ComparingImages()

Func ComparingImages()
    Local $hGUI = GUICreate("Comparing Images", 820, 645)
    ; Create the first pic control, this is the one that we see
    Local $idPic = GUICtrlCreatePic(@ScriptDir & "\Image.jpg", 10, 10, 800, 600)
    ; Crate a second control the exact same width and height as the first. This one can be hidden.
    Local $idPic2 = GUICtrlCreatePic(@ScriptDir & "\Image.jpg", 820, 10, 800, 600)
    ; Startup GDI+ so we can compare the images
    _GDIPlus_Startup()
    Local $bCompare = GUICtrlImageCompare($idPic, $idPic2)
    If (@error) Then
        MsgBox("", "", "Failed to compare the two pic controls" & @CRLF & @error & " | " & @extended)
    Else
        MsgBox("", "", "$idPic and $idPic2 are " & ($bCompare ? "Equal" : "Not equal"))
    EndIf
    Local $bCompare2 = GUICtrlImageCompare($idPic, @ScriptDir & "\Image.jpg")
    If (@error) Then
        MsgBox("", "", "Failed to compare the image control and image file" & @CRLF & @error & " | " & @extended)
    Else
        MsgBox("", "", "$idPic and Image.jpg are " & ($bCompare ? "Equal" : "Not equal"))
    EndIf
    _GDIPlus_Shutdown()

    GUISetState(@SW_SHOW)

    Local $idMsg
    While (True)
        Switch (GUIGetMsg())
            Case $GUI_EVENT_CLOSE
                GUIDelete($hGUI)
                Exit 0
        EndSwitch
    WEnd
EndFunc   ;==>ComparingImages

Func DownloadImage(Const $sDownloadUrl, Const $sSaveAs)
    Local $hDownload = InetGet($sDownloadUrl, $sSaveAs, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)

    While (Not InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE))
        Sleep(100)
    WEnd

    Return FileExists($sSaveAs)
EndFunc   ;==>DownloadImage

; #FUNCTION# ===================================================================
; Name ..........: GUICtrlGetPic
; Description ...: Gets the HBitmap from the image control.
; AutoIt Version : V3.3.14.2
; Syntax ........: GUICtrlGetPic($iCtrlId)
; Parameter(s): .: $iCtrlId     - Control ID returned from GUICtrlCreatePic.
; Return Value ..: Success      - True if the two bitmaps are equal.
;                  Failure      - 0
;                  @ERROR       - @Error and @Extended returned from _GDIPlus_BitmapCreateFromHBITMAP.
; Date ..........: 03/22/2016
; ==============================================================================

Func GUICtrlGetPic($iCtrlId)
    Local $hBitmap = GUICtrlSendMsg($iCtrlId, $STM_GETIMAGE, $IMAGE_BITMAP, 0)
    Local $hGdiBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    Return (@error ? SetError(@error, @extended, 0) : $hGdiBitmap)
EndFunc   ;==>GUICtrlGetPic

; #FUNCTION# ===================================================================
; Name ..........: GUICtrlImageCompare
; Description ...: Compare two images to evaluate if they're the same.
; AutoIt Version : V3.3.14.2
; Syntax ........: GUICtrlImageCompare($lhs, $rhs)
; Parameter(s): .: $lhs         - Control ID returned from GUICtrlCreatePic or a path to an image.
;                  $rhs         - Control ID returned from GUICtrlCreatePic or a path to an image.
; Return Value ..: Success      - True if the two bitmaps are equal.
;                  Failure      - 0
;                  @ERROR       - @Error and @Extended returned from DLLCall for function memcmp.
;                               - -1 if $lhs or $rhs are Hwnd. They must be control IDs.
;                               - 1 $lhs is not a picture control ID and image does not exist.
;                               - 2 $rhs is not a picture control ID and image does not exist.
; Date ..........: 03/22/2016
; ==============================================================================
Func GUICtrlImageCompare($lhs, $rhs)
    If (IsHWnd($lhs) or IsHWnd($rhs)) Then Return SetError(-1, 0, 0)
    ; If $lhs is a control id then we need to get the HBitmap from the control
    If (GUICtrlGetHandle($lhs)) Then
        $lhs = GUICtrlGetPic($lhs)
        If (@error) Then Return SetError(@error, @extended, 0)
    EndIf
    ; If $rhs is a control id then we need to get the HBitmap from the control
    If (GUICtrlGetHandle($rhs)) Then
        $rhs = GUICtrlGetPic($rhs)
        If (@error) Then Return SetError(@error, @extended, 0)
    EndIf
    ; If $lhs is not a control id
    If (Not IsPtr($lhs)) Then
        ; Check to make sure the file exists
        If (Not FileExists($lhs)) Then Return SetError(1, 0, 101)
        ; Load image
        $lhs = _GDIPlus_BitmapCreateFromFile($lhs)
        If (@error) Then Return SetError(@error, 0, 101)
    EndIf
    ; If $rhs is not a control id
    If (Not IsPtr($rhs)) Then
        ; Check to make sure the file exists
        If (Not FileExists($rhs)) Then Return SetError(2, 0, 101)
        ; Load image
        $rhs = _GDIPlus_BitmapCreateFromFile($rhs)
        If (@error) Then Return SetError(@error, 0, 101)
    EndIf
    Local $bCompare = _GDIPlus_BitmapCompareBitmaps($lhs, $rhs)
    Local $iErrorRet = @error
    Local $iExtendedRet = @extended
    ; Clean up resources
    _GDIPlus_BitmapDispose($lhs)
    _GDIPlus_BitmapDispose($rhs)
    Return ($iErrorRet ? SetError($iErrorRet, $iExtendedRet, 0) : $bCompare)
EndFunc

; #FUNCTION# ===================================================================
; Name ..........: _GDIPlus_BitmapCompareBitmaps
; Description ...: Compare two GDI+ bitmap objects to evalaute if they are the same.
; AutoIt Version : V3.3.14.2
; Syntax ........: _GDIPlus_BitmapCompareBitmaps($hBitmap1, $hBitmap2)
; Parameter(s): .: $hBitmap1    - Handle to the first GDI+ bitmap object.
;                  $hBitmap2    - Handle to the second GDI+ bitmap object.
; Return Value ..: Success      - True if the two bitmaps are equal.
;                  Failure      - 0
;                  @ERROR       - @Error and @Extended returned from DLLCall for function memcmp.
; Date ..........: 03/22/2016
; ==============================================================================
Func _GDIPlus_BitmapCompareBitmaps($hBitmap1, $hBitmap2)
    If (Not ($hBitmap1 Or $hBitmap2)) Then Return SetError(10, 0, 0)
    Local $iBitmapWidth1 = _GDIPlus_ImageGetWidth($hBitmap1)
    Local $iBitmapHeight1 = _GDIPlus_ImageGetHeight($hBitmap1)
    Local $iBitmapWidth2 = _GDIPlus_ImageGetWidth($hBitmap2)
    Local $iBitmapHeight2 = _GDIPlus_ImageGetHeight($hBitmap2)
    Local $tBitmapData1 = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $iBitmapWidth1, $iBitmapHeight1, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    Local $tBitmapData2 = _GDIPlus_BitmapLockBits($hBitmap2, 0, 0, $iBitmapWidth2, $iBitmapHeight2, $GDIP_ILMREAD, $GDIP_PXF32RGB)
    Local $iStride1 = DllStructGetData($tBitmapData1, "Stride")
    Local $iStride2 = DllStructGetData($tBitmapData2, "Stride")
    Local $pScan01 = DllStructGetData($tBitmapData1, "Scan0")
    Local $pScan02 = DllStructGetData($tBitmapData2, "Scan0")
    Local $pPtr1 = $pScan01
    Local $pPtr2 = $pScan02
    Local $iSize1 = ($iBitmapHeight1 - 1) * $iStride1 + ($iBitmapWidth1 - 1) * 4
    Local $iSize2 = ($iBitmapHeight2 - 1) * $iStride2 + ($iBitmapWidth2 - 1) * 4
    Local $iSmallest = ($iSize1 < $iSize2 ? $iSize1 : $iSize2)
    Local $aReturn = DllCall("msvcrt.dll", "int:cdecl", "memcmp", "ptr", $pPtr1, "ptr", $pPtr2, "int", $iSmallest)
    Local $iErrorRet = @error
    Local $iExtendedRet = @extended
    _GDIPlus_BitmapUnlockBits($hBitmap1, $tBitmapData1)
    _GDIPlus_BitmapUnlockBits($hBitmap2, $tBitmapData2)
    $tBitmapData1 = 0
    $tBitmapData2 = 0
    Return ($iErrorRet ? SetError($iErrorRet, $iExtendedRet, 0) : $aReturn[0] = 0)
EndFunc   ;==>_GDIPlus_BitmapCompareBitmap

 

Edited by InunoTaishou
Link to comment
Share on other sites

Since there's really no way for me to get the file location; I assigned a variable to represent it's that file.

 

$b = 0 ;1 = test.jpg, 2 = test2.jpg, 3 = test3.jpg, etc...
Test()


Func Test()
guictrlsetimage($img, @scriptdir & "\test.jpg")
$b = 1

checker()
Endfunc


Func checker()

if $b = 1 then
msgbox(0, "Exist", "Image is the same")
Else

;loop

guictrlsetimage($img, @scriptdir & "\test.jpg")
$b = 1
endif



endfunc

 

Msgbox(0, "Hate", "Just hate it when I post a question and find my own answer after a couple tries. But if I don't post the question, I can't seem to resolve it at all.")
Link to comment
Share on other sites

Man, all that work on an image compare function that works with image files and control ids and you didn't even use it!

I'm kidding lol. Honestly it's a lot simpler and accurate to just store file in a variable and access it that way. Here's another way of doing that.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <WinApi.au3>
#include <StaticConstants.au3>
#include <InetConstants.au3>
Global Const $sImage1 = @ScriptDir & "\autoit_metal_wall_800x600.jpg"
Global Const $sImage2 = @ScriptDir & "\autoit_matrix_wall_800x600.jpg"
Global Const $sImage3 = @ScriptDir & "\autoit_builder_wall_800x600.jpg"
Global Const $sImage4 = @ScriptDir & "\autoit9_wall_grey_800x600.jpg"

DownloadImage("https://www.autoitscript.com/autoit3/files/graphics/autoit_metal_wall_800x600.jpg", $sImage1)
DownloadImage("https://www.autoitscript.com/autoit3/files/graphics/autoit_matrix_wall_800x600.jpg", $sImage2)
DownloadImage("https://www.autoitscript.com/autoit3/files/graphics/autoit_builder_wall_800x600.jpg", $sImage3)
DownloadImage("https://www.autoitscript.com/autoit3/files/graphics/autoit9_wall_grey_800x600.jpg", $sImage4)

Example()

Func Example()
    Local $hGUI = GUICreate("Example", 410, 310)
    ; Create the first pic control, this is the one that we see
    Local $idPic1 = GUICtrlCreatePic("", 10, 10, 200, 150)
    Local $idPic2 = GUICtrlCreatePic("", 200, 10, 200, 150)
    Local $idPic3 = GUICtrlCreatePic("", 10, 150, 200, 150)
    Local $idPic4 = GUICtrlCreatePic("", 200, 150, 200, 150)
    GUICtrlSetpic($idPic1, $sImage1)
    GUICtrlSetpic($idPic2, $sImage2)
    GUICtrlSetpic($idPic3, $sImage3)
    GUICtrlSetpic($idPic4, $sImage4)
    GUISetState(@SW_SHOW)

   While (True)
       Local $idMsg = GUIGetMsg()
        Switch ($idMsg)
            Case $GUI_EVENT_CLOSE
                GUIDelete($hGUI)
                Exit 0
            Case $idPic1 to $idPic4
                MsgBox("", "", "You clicked on image " & GUICtrlGetPic($idMsg))
        EndSwitch
    WEnd
EndFunc   ;==>ComparingImages

Func GUICtrlSetpic($iCtrlId, $sImage)
    AccessControlArrayInfo($iCtrlId, $sImage)
    Return GUICtrlSetImage($iCtrlId, $sImage)
EndFunc

Func GUICtrlGetPic($iCtrlId)
    Return AccessControlArrayInfo($iCtrlId, "", False)
EndFunc

Func AccessControlArrayInfo($iCtrlId, $sImage = 0, $bSetData = True)
    Local Static $aControlArray[1]

    If ($bSetData) Then
        If (UBound($aControlArray) <= $iCtrlId) Then ReDim $aControlArray[$iCtrlId + 1]
        $aControlArray[$iCtrlId] = $sImage
    EndIf

    Return ($iCtrlId >= UBound($aControlArray) ? SetError(1, 0, 0) : $aControlArray[$iCtrlId])
EndFunc

Func DownloadImage(Const $sDownloadUrl, Const $sSaveAs)
    Local $hDownload = InetGet($sDownloadUrl, $sSaveAs, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)

    While (Not InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE))
        Sleep(100)
    WEnd

    Return FileExists($sSaveAs)
EndFunc   ;==>DownloadImage

 

Link to comment
Share on other sites

well, I'm working on a traffic light for raspberry pi3 project. Before I do go ahead and develop, I have to know the concept of how this work. So the process works like this:

If 'green light' image is loaded in image control, while the mouse is hover over the 'car position' image then the countdown (30second) doesn't loop. If the light image is 'red light' then loop the countdown so the image will go from red -> yellow -> green. To know rather the image is a green light; I have to identify the image control which image it's loaded with if that make sense. Used mspaint LoL

 

Let me know if you have a better idea...

Street.jpg

Msgbox(0, "Hate", "Just hate it when I post a question and find my own answer after a couple tries. But if I don't post the question, I can't seem to resolve it at all.")
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...