Jump to content

Scrolling Thumbnails


Recommended Posts

In the code below i have it set up so you can choose images and display them in the GUI. You can scroll the images and balloon tips show image name and size. 9 times out of 10 it works great... but "once" in a while it crashes. I'm assuming this has everything to do with memory because i can seem to load a directory of about 50 jpegs and pound the left/right keys without tripping it up. But, as soon as i load a directory of about 25 bmps... it starts to lag. I can pound the scroll all the way to end once, then if i do it a second time, the images start to space out more than they should. I've tried using a small sleep in the do until loops, but that just makes the images jump. Any ideas?

Requires "image_get_size.au3"

You can use the buttons on the left to scroll the images, but it works like a wounded turtle. The real problem is with using the left/right keys.

#include <GUIConstants.au3>
#include <GuiEdit.au3>
#include <file.au3>
#include <array.au3>
#include <image_get_size.au3>

Dim $szDrive, $szDir, $szFName, $szExt
TraySetState (2)

Global $q
Global $t
Global $ATitle = " Test"&Chr("149")&"Me "
$Wrap = GUICreate ($ATitle, 700, 500, -1, -1, -1,"")
GUISetBkColor(0xffffff, $Wrap)

$GetDir = GUICtrlCreateButton("Browse for images", 30, 30, 150, 20, BitOR($BS_FLAT, $BS_CENTER, $BS_VCENTER), "")

$ForI = GUICtrlCreateButton("<", 0, 305, 50, 20, BitOR($BS_FLAT, $BS_CENTER, $BS_VCENTER), "")
$BackI = GUICtrlCreateButton(">", 50, 305, 50, 20, BitOR($BS_FLAT, $BS_CENTER, $BS_VCENTER), "")

GUICtrlSetState($ForI, $GUI_DISABLE)
GUICtrlSetState($BackI, $GUI_DISABLE)

$FileBox = GUICtrlCreateEdit("", 0, 100, 700, 200)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)

GUISetState (@SW_SHOW, $Wrap)

While 1

    $msg = GUIGetMsg()
    Select

        Case $msg = $GetDir
            $File = FileOpenDialog("Open file/files", @DesktopDir, "Images (*.JPG; *.TIFF; *.BMP; *.GIF)", 4+16)
            If @error Then
                MsgBox(0, "", "No File Selected")
            Else
                
                $id = 7
                $q_lr = 0
                If $q > 0 Then

                    Do
                        
                        GUICtrlDelete ($id)
                        If @error Then
                            ExitLoop
                        Else
                            
                            $id = $id + 1
                            $q_lr = $q_lr + 1

                        EndIf
                    Until $q_lr = $q

                EndIf
                
                GUICtrlSetState($ForI, $GUI_DISABLE)
                GUICtrlSetState($BackI, $GUI_DISABLE)
                
                $MediaSplit = _PathSplit($File, $szDrive, $szDir, $szFName, $szExt)
                $FileName = $MediaSplit[3]&$MediaSplit[4]
                $FileDiv = StringSplit($FileName, "|")
                If $FileDiv[0] = "1" Then
                    MsgBox (0,"","Must choose more than one file")
                Else
                    
                    
                    $i=2
                    $l=20
                    $t=0
                    $a = 0
                    $wx = 0
                    $q = 0
                    
                    Do
                        $filebit = FileGetSize($MediaSplit[1]&$MediaSplit[2]&$FileDiv[1]&"\"&$FileDiv[$i])
                        
                        $filebitkb = $filebit/1024
                        $filebitkb = Round($filebitkb)
                        If $filebitkb = 0 Then
                            $filebitkb = $filebit&"Bytes"
                        Else
                            $filebitkb = $filebitkb&"Kb"
                        EndIf
                        
                        $filebitmb = $filebit/1048576
                        $filebitmb = StringLeft($filebitmb, 5)&"Mb"
                        
                        $file = _ImageGetSize($MediaSplit[1]&$MediaSplit[2]&$FileDiv[1]&"\"&$FileDiv[$i])
                        If $file[0] > $file[1] Then
                            $a = $file[0]/100
                        Else
                            $a = $file[1]/100
                        EndIf
                        
                        $w = $file[0]/$a
                        $w = Round ($w)
                        If $w > $file[0] Then
                            $w = $file[0]
                        EndIf
                        
                        $h = $file[1]/$a
                        $h = Round ($h)
                        If $h > $file[1] Then
                            $h = $file[1]
                        EndIF
                        
                        GUICtrlCreatePic ($MediaSplit[1]&$MediaSplit[2]&$FileDiv[1]&"\"&$FileDiv[$i], $l, 350, $w, $h)
                        GUICtrlSetTip (-1, $FileDiv[$i]&@CRLF&$file[0]&"x"&$file[1]&@CRLF&$filebitkb&@CRLF&$filebitmb, "", "", 1)
                        
                        GUICtrlSetData($FileBox, $MediaSplit[1]&$MediaSplit[2]&$FileDiv[1]&"\"&$FileDiv[$i]&@CRLF, 0)
                        $i = $i + 1
                        $l = $l + $w + 50
                        $wx = $wx + $w + 50
                        
                        $q = $q + 1

                    Until $i = $FileDiv[0]+1
                    $CheckWin = WinGetPos ($Wrap, "")

                    $a = $wx * 2
                    $t = $wx - $a + $CheckWin[2] - 20
                    
                    HotKeySet("{LEFT}", "Forward")
                    HotKeySet("{RIGHT}", "Back")
                    GUICtrlSetState($ForI, $GUI_ENABLE)
                    GUICtrlSetState($BackI, $GUI_ENABLE)
                EndIf
                
            EndIf

        Case $msg = $ForI
            Send("{LEFT}")
            
        Case $msg = $BackI
            Send("{RIGHT}")
            
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop

    EndSelect
Wend

Func Back();posotive;right

    $id = 7
    $q_lr = 0
    Do
        $Check = ControlGetPos($Wrap, "", 7)
        If $Check[0] >= 40 Then
            $Next = ControlGetPos($Wrap, "", 8)
            ControlMove ($Wrap,"",7, $Next[0]-$Check[2]-50, 350)
            ExitLoop
        Else
            
            $Cur = ControlGetPos($Wrap, "", $id)
            If @error Then
                ExitLoop
            Else
                ControlMove ($Wrap,"",$id, $Cur[0]+20, 350)
                If @error Then
                    ExitLoop
                Else
                    
                    $id = $id + 1
                    $q_lr = $q_lr + 1
                    
                EndIf
            EndIf
        EndIf
    Until $q_lr = $q

EndFunc

Func Forward();negative;left

    $id = 7
    $q_lr = 0

    Do
        $Check = ControlGetPos($Wrap, "", 7)
        If $Check[0] <= $t Then
            $Next = ControlGetPos($Wrap, "", 8)
            ControlMove ($Wrap,"",7, $Next[0]-$Check[2]-50, 350)
            ExitLoop
        Else
            
            $Cur = ControlGetPos($Wrap, "", $id)
            If @error Then
                ExitLoop
            Else
                ControlMove ($Wrap,"",$id, $Cur[0]-20, 350)
                If @error Then
                    ExitLoop
                Else
                    
                    $id = $id + 1
                    $q_lr = $q_lr + 1

                EndIf
            EndIf
        EndIf
    Until $q_lr = $q

EndFunc

GUIDelete ()

Exit

Sorry about the messy code.

Link to comment
Share on other sites

Hmmm... The UDF for "image_get_size" that I found only does jpeg... Is that not the right one?

I'm looking forward to seeing this!

Oh, and I got this:

C:\Documents and Settings\Owner\Desktop\New AutoIt v3 Script.au3 (111) : ==> Incorrect number of parameters in function call.:

GUICtrlSetTip (-1, $FileDiv[$i]&@CRLF&$file[0]&"x"&$file[1]&@CRLF&$filebitkb&@CRLF&$filebitmb, "", "", 1)

^ ERROR

I changed it to:

GUICtrlSetTip (-1, $FileDiv[$i]&@CRLF&$file[0]&"x"&$file[1]&@CRLF&$filebitkb&@CRLF&$filebitmb)

Changed the function name to GetJpegSize() and it worked, nice script!

Keep up the good work!

Edited by magician13134
Link to comment
Share on other sites

Hmmm... The UDF for "image_get_size" that I found only does jpeg... Is that not the right one?

I'm looking forward to seeing this!

Oh, and I got this:

C:\Documents and Settings\Owner\Desktop\New AutoIt v3 Script.au3 (111) : ==> Incorrect number of parameters in function call.:

GUICtrlSetTip (-1, $FileDiv[$i]&@CRLF&$file[0]&"x"&$file[1]&@CRLF&$filebitkb&@CRLF&$filebitmb, "", "", 1)

^ ERROR

I changed it to:

GUICtrlSetTip (-1, $FileDiv[$i]&@CRLF&$file[0]&"x"&$file[1]&@CRLF&$filebitkb&@CRLF&$filebitmb)

Changed the function name to GetJpegSize() and it worked, nice script!

Keep up the good work!

Lazycat's UDF will get the size of jpeg, tiff, bmp, png and gif (Func _ImageGetSize... just below)

By changing to GetJpegSize(), if you choose to open anything other than jpegs, it will crash. I haven't error checked enough at this point, at least not concerning file get size. I don't have any problems with setting the tip... i don't get any errors. Interesting. Thanks for checking.

;===============================================================================
;
; Description:      Return JPEG, TIFF, BMP, PNG and GIF image size.
; Parameter(s):     File name
; Requirement(s):   None special
; Return Value(s):  On Success - array with width and height
;                   On Failure empty string and sets @ERROR:
;                       1 - Not valid image or info not found
; Author(s):        YDY (Lazycat)
; Version:          1.1.00
; Date:             15.03.2005
;
;===============================================================================

Func _ImageGetSize($sFile)
    Local $sHeader = _FileReadAtOffsetHEX($sFile, 1, 24); Get header bytes
    Local $asIdent = StringSplit("FFD8 424D 89504E470D0A1A 4749463839 4749463837 4949 4D4D", " ")
    Local $anSize = ""
    For $i = 1 To $asIdent[0]
        If StringInStr($sHeader, $asIdent[$i]) = 1 Then
            Select
                Case $i = 1; JPEG
                    $anSize = _ImageGetSizeJPG($sFile)
                    Exitloop
                Case $i = 2; BMP
                    $anSize = _ImageGetSizeSimple($sHeader, 19, 23, 0)
                    Exitloop
                Case $i = 3; PNG
                    $anSize = _ImageGetSizeSimple($sHeader, 19, 23, 1)
                    Exitloop
                Case ($i = 4) or ($i = 5); GIF
                    $anSize = _ImageGetSizeSimple($sHeader, 7, 9, 0)
                    Exitloop
                Case $i = 6; TIFF MM
                    $anSize = _ImageGetSizeTIF($sFile, 0)
                    Exitloop
                Case $i = 7; TIFF II
                    $anSize = _ImageGetSizeTIF($sFile, 1)
                    Exitloop
            EndSelect
        Endif
    Next
    If not IsArray ($anSize) Then SetError(1)
    Return($anSize)
EndFunc

;===============================================================================
;
; Description:      Get image size at given bytes
; Parameter(s):     File header
; Return Value(s):  Array with dimension
;
;===============================================================================
Func _ImageGetSizeSimple($sHeader, $nXoff, $nYoff, $nByteOrder)
    Local $anSize[2]
    $anSize[0] = _Dec(StringMid($sHeader, $nXoff*2-1, 4), $nByteOrder)
    $anSize[1] = _Dec(StringMid($sHeader, $nYoff*2-1, 4), $nByteOrder)
    Return ($anSize)
EndFunc

;===============================================================================
;
; Description:      Get JPG image size (may be used standalone with checking)
; Parameter(s):     File name
; Return Value(s):  On Success - array with dimension
;
;===============================================================================
Func _ImageGetSizeJPG($sFile)
    Local $anSize[2], $sData, $sSeg, $nFileSize, $nPos = 3
    $nFileSize = FileGetSize($sFile)
    While $nPos < $nFileSize
        $sData = _FileReadAtOffsetHEX ($sFile, $nPos, 4)
        If StringLeft($sData, 2) = "FF" then; Valid segment start
            If StringInStr("C0 C2 CA C1 C3 C5 C6 C7 C9 CB CD CE CF", StringMid($sData, 3, 2)) Then; Segment with size data
               $sSeg = _FileReadAtOffsetHEX ($sFile, $nPos + 5, 4)
               $anSize[1] = Dec(StringLeft($sSeg, 4))
               $anSize[0] = Dec(StringRight($sSeg, 4))
               Return($anSize)
            Else
               $nPos= $nPos + Dec(StringRight($sData, 4)) + 2
            Endif
        Else
            ExitLoop
        Endif
    Wend
    Return("")
EndFunc

;===============================================================================
;
; Description:      Get TIFF image size (may be used standalone with checking)
; Parameter(s):     File name
; Return Value(s):  On Success - array with dimension
;
;===============================================================================
Func _ImageGetSizeTIF($sFile, $nByteOrder)
    Local $anSize[2], $pos = 3
    $nTagsOffset = _Dec(_FileReadAtOffsetHEX($sFile, 5, 4), $nByteOrder) + 1
    $nFieldCount = _Dec(_FileReadAtOffsetHEX($sFile, $nTagsOffset, 2), $nByteOrder)
    For $i = 0 To $nFieldCount - 1
        $sField = _FileReadAtOffsetHEX($sFile, $nTagsOffset + 2 + 12 * $i, 12)
        $sTag = StringLeft($sField, 4)
        If $nByteOrder Then $sTag = StringRight($sTag, 2) & StringLeft($sTag, 2)
        Select
            Case $sTag = "0001"
                $anSize[0] = _Dec(StringRight($sField, 8), $nByteOrder)
            Case $sTag = "0101"
                $anSize[1] = _Dec(StringRight($sField, 8), $nByteOrder)
        EndSelect
    Next
    If ($anSize[0] = 0) or ($anSize[1] = 0) Then Return("")
    Return($anSize)
Endfunc

;===============================================================================
;
; Description:      Basic function that read binary data into HEX-string
; Parameter(s):     File name, Start offset, Number bytes to read
; Return Value(s):  Hex string
;
;===============================================================================
Func _FileReadAtOffsetHEX ($sFile, $nOffset, $nBytes)
    Local $hFile = FileOpen($sFile, 0)
    Local $sTempStr = ""
    FileRead($hFile, $nOffset - 1)
    For $i = $nOffset To $nOffset + $nBytes - 1
        $sTempStr = $sTempStr & Hex(Asc(FileRead($hFile, 1)), 2)
    Next
    FileClose($hFile)
    Return ($sTempStr)
Endfunc

;===============================================================================
;
; Description:      Basic function, similar Dec, but take in account byte order
; Parameter(s):     Hex string, Byte order
; Return Value(s):  Decimal value
;
;===============================================================================
Func _Dec($sHexStr, $nByteOrder)
    If $nByteOrder Then Return(Dec($sHexStr))
    Local $sTempStr = ""
    While StringLen($sHexStr) > 0
        $sTempStr = $sTempStr & StringRight($sHexStr, 2)
        $sHexStr = StringTrimRight($sHexStr, 2)
    WEnd
    Return (Dec($sTempStr))
EndFunc
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...