mikell Posted December 22, 2009 Share Posted December 22, 2009 Hello I'm trying to make a desktop animation, which uses 1800 png files with transparency, around 20 Ko each. Here is the piece of script : _GDIPlus_Startup() For $i = 0 to 1800 $hImage = _GDIPlus_ImageLoadFromFile($path & $i & ".png") SetBitMap($hGUI, $hImage, 255) GUISetState() _GDIPlus_ImageDispose($hImage) Sleep(20) Next _GDIPlus_Shutdown() It works, but I can see my HD working hard and the anim is slow. But, when I play the anim a second time, then it plays correctly and my HD keeps quiet. I suppose there is some kind of writing in a cache when the images "load" the first time, and a simple read of this cache the second time. If before the script I put this : For $i = 0 to 1800 $hImage = _GDIPlus_ImageLoadFromFile($path & $i & ".png") _GDIPlus_ImageDispose($hImage) Next then there is a (long) silent loading and after this the anim plays correctly. So my question is : is it possible to avoid this delay before playing, and to play the anim in a "progressive" way ? or, is there a way to reduce this caching delay ? I found some things about using libpng.dll but I dont know how to put this to Autoit... Thanks a lot for any information Merry Xmas to all Link to comment Share on other sites More sharing options...
martin Posted December 22, 2009 Share Posted December 22, 2009 (edited) Hello I'm trying to make a desktop animation, which uses 1800 png files with transparency, around 20 Ko each. Here is the piece of script : _GDIPlus_Startup() For $i = 0 to 1800 $hImage = _GDIPlus_ImageLoadFromFile($path & $i & ".png") SetBitMap($hGUI, $hImage, 255) GUISetState() _GDIPlus_ImageDispose($hImage) Sleep(20) Next _GDIPlus_Shutdown() It works, but I can see my HD working hard and the anim is slow. But, when I play the anim a second time, then it plays correctly and my HD keeps quiet. I suppose there is some kind of writing in a cache when the images "load" the first time, and a simple read of this cache the second time. If before the script I put this : For $i = 0 to 1800 $hImage = _GDIPlus_ImageLoadFromFile($path & $i & ".png") _GDIPlus_ImageDispose($hImage) Next then there is a (long) silent loading and after this the anim plays correctly. So my question is : is it possible to avoid this delay before playing, and to play the anim in a "progressive" way ? or, is there a way to reduce this caching delay ? I found some things about using libpng.dll but I dont know how to put this to Autoit... Thanks a lot for any information Merry Xmas to all I would try something like (though I haven't) expandcollapse popup$frameTime = 20 $playTime = 1801 * $frametime $TimeToload=0 $Frame = 0 OnAutoItExitRegister("clean") Dim $hImage[1801] _GDIPlus_Startup() $startTime = TimerInit() $playing = false For $i = 0 to 1800;should this really be from 0? $hImage[$i] = _GDIPlus_ImageLoadFromFile($path & $i & ".png") if not $playing and $i>10 then ; maybe 10 is too few? $Avtime = TimerDiff($startTime)/($i+1) $TimeToLoad = (1801-$1)*$Avtime if $TimeToLoad < $playTime then ; + $someSafetyMargin? AdlibRegister("Play",$frameTime) $playing = True endif endif Next while 1 sleep(100) if $frame >= 1801 then exit next Func Play() SetBitMap($hGUI, $hImage[$frame], 255) GUISetState();is this needed? ;possibly dispose of last image here ;_GDIPlus_ImageDispose($hImage[$Frame]) $frame += 1 wend Func Clean() For $i = 0 to 1800 _GDIPlus_ImageDispose($hImage[$i]) Next _GDIPlus_Shutdown() EDIT: Welcome to the AutoIt forums mikell Edited December 22, 2009 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
mikell Posted December 22, 2009 Author Share Posted December 22, 2009 Thanks martin for your answer "should this really be from 0?" No, you're right, my first image is ' 0.png' but $hImage[0] doesn't work. In fact my anim is 1875 images long, it begins (now) at '1.png' and ends at '1874.png'. I could manage your script in this way : expandcollapse popup$frameTime = 20 $playTime = 1874 * $frametime $TimeToload=0 $Frame = 0 ;Opt("OnExitFunc", "clean") Dim $hImage[1875] _GDIPlus_Startup() $startTime = TimerInit() $playing = false For $i = 1 to 1874 ;should this really be from 0? $hImage[$i] = _GDIPlus_ImageLoadFromFile($path & $i & ".png") If not $playing and $i>10 Then ; maybe 10 is too few? $Avtime = TimerDiff($startTime)/($i+1) $TimeToLoad = (1875-$i)*$Avtime If $TimeToLoad < $playTime Then ; + $someSafetyMargin? AdlibEnable("Play",$frameTime) $playing = True Endif Endif $frame += 1 Next while 1 sleep(100) If $frame >= 1874 Then Clean() Exit Endif wend _GDIPlus_Shutdown() Func Play() SetBitMap($hGUI, $hImage[$frame], 255) EndFunc Func Clean() For $i = 1 to 1874 _GDIPlus_ImageDispose($hImage[$i]) Next EndFunc it's much better, but now there is a funny thing occuring : the first time the anim plays correctly, and the second time it runs like a rocket Is there a way for the anim to "learn" if it is its first run or not, maybe by detecting if images are already loaded in cache ? The problem is, I have absolutely no idea about how to do that... Link to comment Share on other sites More sharing options...
martin Posted December 23, 2009 Share Posted December 23, 2009 Thanks martin for your answer "should this really be from 0?" No, you're right, my first image is ' 0.png' but $hImage[0] doesn't work. In fact my anim is 1875 images long, it begins (now) at '1.png' and ends at '1874.png'. I could manage your script in this way : expandcollapse popup$frameTime = 20 $playTime = 1874 * $frametime $TimeToload=0 $Frame = 0 ;Opt("OnExitFunc", "clean") Dim $hImage[1875] _GDIPlus_Startup() $startTime = TimerInit() $playing = false For $i = 1 to 1874 ;should this really be from 0? $hImage[$i] = _GDIPlus_ImageLoadFromFile($path & $i & ".png") If not $playing and $i>10 Then ; maybe 10 is too few? $Avtime = TimerDiff($startTime)/($i+1) $TimeToLoad = (1875-$i)*$Avtime If $TimeToLoad < $playTime Then ; + $someSafetyMargin? AdlibEnable("Play",$frameTime) $playing = True Endif Endif $frame += 1 Next while 1 sleep(100) If $frame >= 1874 Then Clean() Exit Endif wend _GDIPlus_Shutdown() Func Play() SetBitMap($hGUI, $hImage[$frame], 255) EndFunc Func Clean() For $i = 1 to 1874 _GDIPlus_ImageDispose($hImage[$i]) Next EndFunc it's much better, but now there is a funny thing occuring : the first time the anim plays correctly, and the second time it runs like a rocket Is there a way for the anim to "learn" if it is its first run or not, maybe by detecting if images are already loaded in cache ? The problem is, I have absolutely no idea about how to do that... I don't see how you run the second time. If you simply run the whole script again for th esecond time then I think that Windows is caching the data read from the disc. If the $frametime value is the same then I don't see how it runs faster the second time, unless you mean it starts sooner in which case I do understand. But to run again it would be better just to set the frame count to 0 and let the adlib carry on, then it would also be very quick to start providing you hadn't disposed of the graphic handles. This will make the animation run 3 times. expandcollapse popup$frameTime = 20 $playTime = 1874 * $frametime $TimeToload=0 $Frame = 0 ;Opt("OnExitFunc", "clean") Dim $hImage[1875] _GDIPlus_Startup() $startTime = TimerInit() $playing = false For $jj = 1 to 3 For $i = 1 to 1874 ;should this really be from 0? $hImage[$i] = _GDIPlus_ImageLoadFromFile($path & $i & ".png") If not $playing and $i>10 Then ; maybe 10 is too few? $Avtime = TimerDiff($startTime)/($i+1) $TimeToLoad = (1875-$i)*$Avtime If $TimeToLoad < $playTime Then ; + $someSafetyMargin? AdlibEnable("Play",$frameTime) $playing = True Endif Endif $frame += 1 Next $frame = 0 Next while 1 sleep(100) If $frame >= 1874 Then Clean() Exit Endif wend _GDIPlus_Shutdown() Func Play() SetBitMap($hGUI, $hImage[$frame], 255) EndFunc Func Clean() For $i = 1 to 1874 _GDIPlus_ImageDispose($hImage[$i]) Next EndFunc Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
mikell Posted December 23, 2009 Author Share Posted December 23, 2009 martin, to play the anim I run the whole script, and this script automatically exits at the end of the anim. At the first run, the anim plays well but I see my HD at work, so I suppose that Windows is loading the images "somewhere" and memorizing "something", because if I run the script a second time (or more) then the anim plays much quicker. If I reboot my PC and run the script, it works as a first run. I think the "somewhere" and the "something" has been cleaned up during the reboot. If I could know about these "somewhere" and "something" then I should include in the script a condition for playing the anim in 2 different ways. My english is approximative so forgive me if my explanations are not very clear Link to comment Share on other sites More sharing options...
mikell Posted December 23, 2009 Author Share Posted December 23, 2009 Pfff impossible to learn where GDI+ memorizes these data There is a solution, it is tricky and not satisfying but I tested it several times and it works expandcollapse popup$frameTime = 30 $playTime = 1874 * $frametime $TimeToload=0 $Frame = 0 Dim $hImage[1875] _GDIPlus_Startup() $startTime = TimerInit() $playing = false For $i = 1 to 1874 $test = TimerInit() $hImage[$i] = _GDIPlus_ImageLoadFromFile($path & $i & ".png") If TimerDiff($test) < 5 Then ; <---------------------------- here is the trick SetBitMap($hGUI, $hImage[$i], 255) _GDIPlus_ImageDispose($hImage[$i]) Sleep(20) Else If not $playing and $i>10 Then $Avtime = TimerDiff($startTime) /($i+1) $TimeToLoad = (1875-$i)*$Avtime If $TimeToLoad < $playTime Then AdlibEnable("Play",$frameTime) $playing = True Endif Endif Endif $frame += 1 Next while 1 sleep(100) If $frame >= 1874 Then Clean() Exit Endif wend _GDIPlus_Shutdown() Func Play() SetBitMap($hGUI, $hImage[$frame], 255) EndFunc Func Clean() For $i = 1 to 1874 _GDIPlus_ImageDispose($hImage[$i]) Next EndFunc something like : If (ImageLoadingTime < 5) then my original script else martin's script endif thank you martin, have nice Xmas and new year Link to comment Share on other sites More sharing options...
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