Sign in to follow this  
Followers 0
wysocki

Slideshow using GUICtrlSetimage flickers

2 posts in this topic

I wanted a screensaver app that I could call from another program but everything I tried took so much resources that it dragged on my celeron 500 tablet. I wrote a small slideshow script (using cannibalized code from this forum) and it works fine. Except that when the images change, there's a nasty screen flicker. Is there any way to make the image transition smoother?

$dir = "c:\pictures";folder to display pictures from
$delaysecs = 4;time delay between slides
$numpics = 0;create a text file with filenames to loop through
$search = FileFindFirstFile($dir & "\*.jpg")
$piclist = FileOpen (@TempDir & "\pic.txt",2)   
While 1;load pic.txt with picture filenames
   $file = FileFindNextFile($search)
   If @error Then ExitLoop
    FileWriteLine ($piclist,$dir & "\" & $file)
    $numpics=$numpics+1
WEnd
FileClose ($piclist)
$piclist = FileOpen (@TempDir & "\pic.txt",0)
#include <GuiConstants.au3>
GuiCreate("slideshow", @DesktopWidth, @DesktopHeight,-1,-1,$WS_POPUPWINDOW)
$pic = GuiCtrlCreatePic(FileReadLine ($piclist), 0, 0,@DesktopWidth, @DesktopHeight)
GuiCtrlSetState(-1,$GUI_DISABLE);allows other controls to overlap
$Button_exit = GuiCtrlCreateButton("EXIT", 0, @DesktopHeight - 50, 80, 50)
GuiSetState()
$starttime = 0
$picnum = 1
While 1
   $msg = GUIGetMsg()
   If $msg = $Button_exit Then ExitLoop
   If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    If TimerDiff($starttime) > $delaysecs * 1000 Then
        $starttime = TimerInit()
        GUICtrlSetimage($pic,FileReadLine ($piclist,$picnum))
        $picnum = $picnum + 1
        If $picnum > $numpics Then $picnum = 1
    EndIf
Wend
Exit

Share this post


Link to post
Share on other sites



Pardon me for answering my own question, but after hours of searching the forum and experimenting with my own code, and cannibalizing others (thanks Lazycat!), I've come up with a working slideshow. Deleting and restarting the image display cleaner than using GUICtrlSetimage, plus it allow me to rescale for each image. Just point to the folder and set the delay time and it'll scale and display jpg images randomly. To use it for non jpg images you'll have to get Lazycat's other image functions but this works fine for me.

$dir = "c:\pictures"
$delaysecs = 7
#include <GuiConstants.au3>
#include <Array.au3>
$pic=0
$picnum=0
$newpicnum=0
$numpics = 0
$search = FileFindFirstFile($dir & "\*.jpg")
$piclist = FileOpen (@TempDir & "\pic.txt",2)   
While 1;load pic.txt with picture filenames
   $file = FileFindNextFile($search)
   If @error Then ExitLoop
    FileWriteLine ($piclist,$dir & "\" & $file)
    $numpics=$numpics+1
WEnd
FileClose ($piclist)
$piclist = FileOpen (@TempDir & "\pic.txt",0)
GuiCreate("SlideShow", @DesktopWidth, @DesktopHeight,-1,-1,$WS_POPUPWINDOW)
GUISetBkColor ( 0x000000)
GuiSetState()
MouseMove(@DesktopWidth+1, @DesktopHeight+1, 0)
showpic()
$starttime = TimerInit()
While 1
   $msg = GUIGetMsg()
   If $msg = $pic Then ExitLoop
   If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    If TimerDiff($starttime) > $delaysecs * 1000 Then
        showpic()
        $starttime = TimerInit()
    EndIf
Wend
Exit

Func showpic ()
    While $newpicnum = $picnum
        $newpicnum = Random(1,$numpics,1)
    WEnd
    $picnum=$newpicnum
    $fname=FileReadLine ($piclist,$picnum)
    $avArray=_ImageGetSizeJPG($fname)
    $PicWinWidth=@DesktopWidth
    $PicWinHeight=@DesktopHeight
    If Abs($avArray[0] / $avArray[1] - @DesktopWidth / @DesktopHeight) < .1 Then
    ;don't adjust aspect ratio if it's within close range, just stretch to fullscreen
    ElseIf $avArray[0] / $avArray[1] > @DesktopWidth / @DesktopHeight Then;overwidth
        $PicWinHeight=@DesktopWidth * $avArray[1] / $avArray[0]
    ElseIf $avArray[0] / $avArray[1] < @DesktopWidth / @DesktopHeight Then;overheight
        $PicWinWidth=@DesktopHeight * $avArray[1] / $avArray[0]
    EndIf   
    GUICtrlDelete($pic)
    $pic = GuiCtrlCreatePic($fname, (@DesktopWidth - $PicWinWidth) / 2, (@DesktopHeight - $PicWinHeight) / 2,$PicWinWidth, $PicWinHeight )
EndFunc

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

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  
Followers 0