Jump to content
Sign in to follow this  
timmy2

Is it possible to simulate a dual-projector slide show using AutoIt?

Recommended Posts

To save future readers a little sweat I'm editing my original post to insert the following:

After trying various suggested scripting approaches, some of which introduced new problems and some which had the same problem described here, I tried my script and a few others on another computer. No white flashes, tears, glitches. So I brought it back to my main box and disabled the Intel GPU that was feeding a 3rd monitor. Down to two monitors connected to a single NVidia GPU the visual glitches disappeared. Who would'a thought?!

That said, some of the replies that follow provide valuable insights into the various ways to skin this cat using AutoIt.  Some suggested scripts introduced new problems so they might be instructive about approaches to avoid. Ultimately, JohnOne suggested an elegantly simple script that perfectly accomplishes my goal.

---------------------

I want to display a  800x600 picture (i.e., not full-screen) without a border, close-box, title, etc.  I then want to replace that picture with another one -- cleanly. Think of an old-fashioned dual-projector slide show where there's no black-out or other interruption to the image on screen. This way I can start with a background image, then add elements to it seamlessly (once called "a build", i.e., pseudo-animation).  The image format doesn't matter to me.

I can't use an animated GIF or video because my code is doing things in the background between images, so timing varies.

I'm having bad luck using an AutoIt form to accomplish this (GUICtrlCreatePic, followed by subsequent GUICtrlSetImage's).  The result is a glitch -- usually a white flash or tear in the picture -- at almost every image change. (see 10/10/13 post entitled "random visual glitch when using GUICtrlSetImage"). So I guess that's out.

SplashImageOn  blanks out the first image before displaying the next (like a single-projector slide show), so it's not seamless -- plus there's still a tiny border visible.

$var = Default

SplashImageOn("","image1.bmp",$var,$var,$var,$var,1)
sleep(2000)
SplashImageOn("","image2.bmp",$var,$var,$var,$var,1)
sleep(2000)
SplashImageOn("","image3.bmp",$var,$var,$var,$var,1)
sleep(2000)

Any suggestions?

Edited by timmy2

Share this post


Link to post
Share on other sites

Have you tried using a borderless gui? I'm pretty sure images can be loaded and layered using GDI+


010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Share this post


Link to post
Share on other sites

Have you tried using a borderless gui? I'm pretty sure images can be loaded and layered using GDI+

 

Thank you for replying, kaotkbliss. 

Could you give me a simple example?   As I mentioned in my original post I've tried GuiCreate/GuiCtrlCreatePic/GuiCtrlSetImage but every GuiCtrlSetImage causes a tear/white flash in the image area -- so it's not clean. 

Maybe "GDI+" is different but I wouldn't know which "_GDIPlus..." commands would be applicable. Moreover, the help file seems a bit cryptic in this area. For example, "_GDIPlus_BitmapCreateFromFile" might be useful but I see no mention of options to make the GUI borderless, and the included example is rather complex and deals with saving a screen capture in a typical gui box.

Plus, I'm concerned that I could pursue trying to learn enough about GDI+ to replace what I did (see below) using the aforementioned GUI commands and end up discovering the result has similar problems.  I'm really surprised GUICtrlSetImage can't display an image over an existing one without tearing.

$form=GUICreate("Test",900,530,518,272, BitOR($WS_SYSMENU,$WS_POPUP), 0)
$cid=GUICtrlCreatePic(@ScriptDir & "\imagebackground.bmp", 0,0, 900, 530)
GuiCtrlSetState($cid,$GUI_DISABLE)

$PSimage=GUICtrlCreatePic(@ScriptDir & "\image1.bmp", 0,0,900,530)

GUISetState(@SW_SHOW)  ;show 1st image
MsgBox(0,"","test")    ;simulate doing some background business before next image is displayed

GUICtrlSetImage($PSimage, @ScriptDir & "\image2.bmp") ;show 2nd image
MsgBox(0,"","test")

GUICtrlSetImage($PSimage,@ScriptDir & "\image3.bmp")  ;show 3rd image
MsgBox(0,"","test")

GUICtrlSetImage($PSimage,@ScriptDir & "\image4.bmp")  'show 4th image
MsgBox(0,"","test")

Exit
Edited by timmy2

Share this post


Link to post
Share on other sites

Also it might work better in a gui instead of splash, look into popup and borderless (can't remember the exact combination off hand but there's tons of examples here in the forums) styles for the guicreate options. Also, you can make the gui completely transparent if you have any troubles with edges


010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Share this post


Link to post
Share on other sites

You're probably thinking of the $WS_POPUP style for the GUI?


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

:huh2: Why not actually do it the way a two projector setup would.

Load slide 1 in projector 1

turn on projector 1 lamp

load slide 2 in projector 2

wait for slide advance

turn on projector 2 lamp

turn off projector 1 lamp

load slide 3 in projector 1

wait for slide advance

etc...

#include <WindowsConstants.au3>

$form=GUICreate("Test",900,530,518,272, BitOR($WS_SYSMENU,$WS_POPUP), 0)

$PSimage1=GUICtrlCreatePic(@ScriptDir & "\image1.bmp", 0,0,900,530) ;load slide 1 for 'projector' 1
GUICtrlSetState($PSimage1, @SW_SHOW) ;show 'projector' 1

GUISetState(@SW_SHOW, $form) ; start showing it

$PSimage2=GUICtrlCreatePic(@ScriptDir & "\image2.bmp", 0,0,900,530) ;load slide 2 for 'projector' 2
GUICtrlSetState($PSimage1, @SW_HIDE) ;hide 'projector' 2

MsgBox(0, "slideshow", "slide 1") ;wait for slide advance

GUICtrlSetState($PSimage2, @SW_SHOW) ;show 'projector' 2
GUICtrlSetState($PSimage1, @SW_HIDE) ;hide 'projector' 1
GUICtrlSetImage($PSimage1,@ScriptDir & "\image3.bmp") ;load slide 3 for 'projector; 1

MsgBox(0, "slideshow", "slide 2") ;wait for slide advance

GUICtrlSetState($PSimage1, @SW_SHOW) ;show 'projector' 1
GUICtrlSetState($PSimage2, @SW_HIDE) ;hide 'projector' 2
GUICtrlSetImage($PSimage2,@ScriptDir & "\image4.bmp") ;load slide 4 for 'projector; 2

MsgBox(0, "slideshow", "slide 3") ;wait for slide advance

GUICtrlSetState($PSimage2, @SW_SHOW) ;show 'projector' 2
GUICtrlSetState($PSimage1, @SW_HIDE) ;hide 'projector' 1
;GUICtrlSetImage($PSimage1,@ScriptDir & "\image5.bmp") ;load slide 5 for 'projector; 1

MsgBox(0, "slideshow", "slide 4") ;wait for slide advance

Exit

No flash on my system when I tested it.

Edited by willichan

Share this post


Link to post
Share on other sites

post-76101-0-58802900-1381553047_thumb.jpost-76101-0-07246100-1381553048_thumb.jpost-76101-0-50418100-1381553048_thumb.jpost-76101-0-77722600-1381553048_thumb.j

Thank you for the comprehensive reply!

The only problem with your script is that image3.jpg doesn't display. I've stared at the script for 15 minutes and feel like an idiot because your script is so simple and makes perfect sense, yet image4.jpg appears for "Slide 3" and for "Slide 4".  I've attached the sample images (jpeg's to keep file sizes small).  I did a search/replace in your script to replace .bmp with .jpg. Please try running this script with my images and tell me if you get the same result.  And, thank you again.

#include <WindowsConstants.au3>

$form=GUICreate("Test",900,530,518,272, BitOR($WS_SYSMENU,$WS_POPUP), 0)

$PSimage1=GUICtrlCreatePic(@ScriptDir & "\image1.jpg", 0,0,900,530) ;load slide 1 for 'projector' 1
GUICtrlSetState($PSimage1, @SW_SHOW) ;show 'projector' 1

GUISetState(@SW_SHOW, $form) ; start showing it

$PSimage2=GUICtrlCreatePic(@ScriptDir & "\image2.jpg", 0,0,900,530) ;load slide 2 for 'projector' 2
GUICtrlSetState($PSimage1, @SW_HIDE) ;hide 'projector' 2

MsgBox(0, "slideshow", "slide 1") ;wait for slide advance

GUICtrlSetState($PSimage2, @SW_SHOW) ;show 'projector' 2
GUICtrlSetState($PSimage1, @SW_HIDE) ;hide 'projector' 1
GUICtrlSetImage($PSimage1,@ScriptDir & "\image3.jpg") ;load slide 3 for 'projector; 1

MsgBox(0, "slideshow", "slide 2") ;wait for slide advance

GUICtrlSetState($PSimage1, @SW_SHOW) ;show 'projector' 1
GUICtrlSetState($PSimage2, @SW_HIDE) ;hide 'projector' 2
GUICtrlSetImage($PSimage2,@ScriptDir & "\image4.jpg") ;load slide 4 for 'projector; 2

MsgBox(0, "slideshow", "slide 3") ;wait for slide advance

GUICtrlSetState($PSimage2, @SW_SHOW) ;show 'projector' 2
GUICtrlSetState($PSimage1, @SW_HIDE) ;hide 'projector' 1
;GUICtrlSetImage($PSimage1,@ScriptDir & "\image5.jpg") ;load slide 5 for 'projector; 1

MsgBox(0, "slideshow", "slide 4") ;wait for slide advance

Exit

Share this post


Link to post
Share on other sites

#include <WindowsConstants.au3>

$form=GUICreate("Test",900,530,518,272, BitOR($WS_SYSMENU,$WS_POPUP), 0)

$PSimage4=GUICtrlCreatePic(@ScriptDir & "\image4.jpg", 0,0,900,530) ;load slide 1 for 'projector' 1
$PSimage3=GUICtrlCreatePic(@ScriptDir & "\image3.jpg", 0,0,900,530)
$PSimage2=GUICtrlCreatePic(@ScriptDir & "\image2.jpg", 0,0,900,530)
$PSimage1=GUICtrlCreatePic(@ScriptDir & "\image1.jpg", 0,0,900,530)
GUISetState(@SW_SHOW, $form) ; start showing it

MsgBox(0, "slideshow", "slide 1") ;wait for slide advance
GUICtrlDelete($PSimage1)

MsgBox(0, "slideshow", "slide 2") ;wait for slide advance
GUICtrlDelete($PSimage2)

MsgBox(0, "slideshow", "slide 3") ;wait for slide advance
GUICtrlDelete($PSimage3)

MsgBox(0, "slideshow", "slide 4") ;wait for slide advance


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

@JohnOne - cleaner way of doing it:

#include <WindowsConstants.au3>

$form = GUICreate("Test", 900, 530, 518, 272, BitOR($WS_SYSMENU, $WS_POPUP), 0)

Global $PSimages[4]
For $i = UBound($PSimages) - 1 To 0 Step -1
    $PSimages[$i] = GUICtrlCreatePic(@ScriptDir & "\image" & $i + 1 & ".jpg", 0, 0, 900, 530)
Next
GUISetState(@SW_SHOW, $form) ; start showing it

For $i = 0 To UBound($PSimages) - 1
    MsgBox(0, "slideshow", "slide " & $i + 1) ;wait for slide advance
    GUICtrlDelete($PSimages[$i])
Next
Edited by DatMCEyeBall

"Just be fred, all we gotta do, just be fred."  -Vocaliod

"That is a Hadouken. A KAMEHAMEHA would have taken him 13 days and 54 episodes to form." - Roden Hoxha

@tabhooked

Clock made of cursors ♣ Desktop Widgets ♣ Water Simulation

Share this post


Link to post
Share on other sites

Pre-loading all of the images works well if there are only a small set, but if the slideshow has a lot of images, you will be using more memory that you may want to.

@timmy2:  I'll take a look at it.

Share this post


Link to post
Share on other sites

datmc result.zippost-76101-0-34698600-1381599622_thumb.jpost-76101-0-77341400-1381599622_thumb.jpost-76101-0-27482500-1381599623_thumb.jpost-76101-0-60130000-1381599623_thumb.j

Thank you DatMCEyeBall and John One.  Using the jpegs I provided previously both of your scripts work with rarely a glitch (the exception being an occasional white flash before the first image ).

BUT... when I substitute my actual photographs, or even slightly more demanding images, problems become visible.  (Note that my Windows 8 background is a solid color: 80,80,80, in case that's a factor.)

DatMCEyeBall's script exhibits three problems:

1. the occasional white flash or tear before the first image, between images, and after the last image. See the attached Camtasia recording.

2. with the attached images you see all four images briefly load at the start

3. as you click through them you see a brief preview of the slide that will follow. I'll have to describe this issue because I couldn't capture it with Camtasia:  run the script, click OK on the first msg box, after that you'll see "Image 3" appear briefly followed by the desired "Image 2".  Likewise, "Image 4" appears briefly before "Image 3". This suggests that JohnOne's idea of loading up all four images ("controls") and removing them one by one allows controls underneath to briefly appear at each slide change.

I hope you don't take the foregoing as criticism; I created this post because I couldn't avoid the glitches between images with my code so I figured folks here with far more experience would know the secret recipe.  For me to try to learn GDI+ as one contributor suggested is daunting if it's just going to end up yielding the same problems, so I greatly appreciate the example code DatMCEyeBall and JohnOne provided.

Come to think of it, I should try this on another computer. The one I'm working on, albeit a zippy SSD-based 32GB I7-3770 with 3 monitors, is using a combination of an Nvidia card for two monitors and the built-in Intel GPU for the one that the script is running on. I'll try it on another less complicated rig and report back.(But since Camtasia captures the flashes I suspect these problems are hardware independent.)

Edited by timmy2

Share this post


Link to post
Share on other sites

Try this ex style

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>


$form=GUICreate("Test",900,530,518,272,BitOR($WS_SYSMENU,$WS_POPUP),$WS_EX_COMPOSITED)


$PSimage=GUICtrlCreatePic(@ScriptDir & "\image1.jpg", 0,0,900,530)
GUISetState(@SW_SHOW)
MsgBox(0,"","test")

GUICtrlSetImage($PSimage, @ScriptDir & "\image2.jpg")
MsgBox(0,"","test")

GUICtrlSetImage($PSimage,@ScriptDir & "\image3.jpg")
MsgBox(0,"","test")

GUICtrlSetImage($PSimage,@ScriptDir & "\image4.jpg")
MsgBox(0,"","test")

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

 

Try this ex style

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>


$form=GUICreate("Test",900,530,518,272,BitOR($WS_SYSMENU,$WS_POPUP),$WS_EX_COMPOSITED)


$PSimage=GUICtrlCreatePic(@ScriptDir & "\image1.jpg", 0,0,900,530)
GUISetState(@SW_SHOW)
MsgBox(0,"","test")

GUICtrlSetImage($PSimage, @ScriptDir & "\image2.jpg")
MsgBox(0,"","test")

GUICtrlSetImage($PSimage,@ScriptDir & "\image3.jpg")
MsgBox(0,"","test")

GUICtrlSetImage($PSimage,@ScriptDir & "\image4.jpg")
MsgBox(0,"","test")

 

Magnifique!  Seamless display of my actual images as well as all test images. No artifacts. No flashes. Nada.  Thank you, JohnOne! (would it help other readers for you to explain in simple terms why the "GUI double buffering" solved the problems -- if indeed that was the sole solution?)

um6i.jpg

Edited by timmy2

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  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By therks
      So normally you can use the arrow keys in a GUI to walk through all the controls, not unlike the tab key. But I recently realized that if you put a Pic control in the midst of your normal controls it interrupts the ability to move through the controls (the tab key still works). I really liked the arrow key functionality, and I'm wondering if there's a way to restore that capability without capturing and processing the arrow keys manually, or just moving the Pic creation to a different part of the code.
      I've whipped up a bit of code with some examples:
      #include <GUIConstants.au3> $sPic = StringLeft(@AutoItExe, StringInStr(@AutoItExe, '\', 0, -1)) & '\Examples\GUI\logo4.gif' ; This is the normal behaviour I'd like to keep. GUICreate('Good Example', 250, 150, @DesktopWidth/2 - 250) GUICtrlCreateButton('Button', 50, 0, 200, 30) GUICtrlCreateButton('Button', 50, 30, 200, 30) GUICtrlCreateButton('Button', 50, 60, 200, 30) GUICtrlCreateButton('Button', 50, 90, 200, 30) GUICtrlCreateButton('Button', 50, 120, 200, 30) GUISetState() While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd GUIDelete() ; This is the bad behaviour I'd like to avoid. GUICreate('Example 2', 250, 150, @DesktopWidth/2 - 250) GUICtrlCreatePic($sPic, 0, 0, 50, 30) GUICtrlCreateButton('Button', 50, 0, 200, 30) GUICtrlCreatePic($sPic, 0, 30, 50, 30) GUICtrlCreateButton('Button', 50, 30, 200, 30) GUICtrlCreatePic($sPic, 0, 60, 50, 30) GUICtrlCreateButton('Button', 50, 60, 200, 30) GUICtrlCreatePic($sPic, 0, 90, 50, 30) GUICtrlCreateButton('Button', 50, 90, 200, 30) GUICtrlCreatePic($sPic, 0, 120, 50, 30) GUICtrlCreateButton('Button', 50, 120, 200, 30) GUISetState() While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd GUIDelete() ; This is almost what I want, but notice it doesn't "loop" around like the first example. ; And also having to create the pictures out of sequence with the buttons is not ideal. GUICreate('Example 3', 250, 150, @DesktopWidth/2 - 250) GUICtrlCreateButton('Button', 50, 0, 200, 30) GUICtrlCreateButton('Button', 50, 30, 200, 30) GUICtrlCreateButton('Button', 50, 60, 200, 30) GUICtrlCreateButton('Button', 50, 90, 200, 30) GUICtrlCreateButton('Button', 50, 120, 200, 30) GUICtrlCreatePic($sPic, 0, 0, 50, 30) GUICtrlCreatePic($sPic, 0, 30, 50, 30) GUICtrlCreatePic($sPic, 0, 60, 50, 30) GUICtrlCreatePic($sPic, 0, 90, 50, 30) GUICtrlCreatePic($sPic, 0, 120, 50, 30) GUISetState() While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd GUIDelete() The first GUI that opens demonstrates the behaviour I like. The second GUI demonstrates the problem. The third GUI is almost a solution, but the focus won't wrap around (eg: You can't just hold the down arrow and have the focus loop through the buttons, it sticks at the end). Also creating the pic controls out of sequence with the buttons makes my code harder to read.
    • By rudi
      Hello,
      the following script is running quite nicely for a friend of mine doing a year of work and travel to have a backup at home for all the pics and movies taken with her mobile phone,
       
      The facts:
       
      At home: a VMWARE virtual machine with dropbox installed for her DB account
      On-the-Road: One mobile phone, Camera Uploads are activated for her dropbox account, one Laptop.
       
       
      The idea is to have a copy of *ALL* pictures and movies taken with the mobile phone *OUTSIDE* the dropbox folder, so that the DB Max Size is never exceeded.
      The script is running at home and doing this:
      Copy all content from the "Camera Upload Folder" within the dropbox folder to some folder *OUTSIDE* the DB folder Move all content from the "Camera Upload Folder" do some other folder *INSIDE* the DB folder to indicate, that the backup copies at home were done successfully  
      Dropbox is also installed on the Laptop she has with her. So on the Laptop she checks from time to time the destination folder inside the dropbox folder and moves the pics / movies on the laptop to some other folder outside the dropbox as well. By that final step the images are moved out of the dropbox on the mobile phone as well, so that there is always space left to sync more pics / movies.
       
      As moving pics / movies out of the dropbox folder on the laptop doesn't touch the copies in the mobile phone's "Gallery", she has all the pics / movies at all three locations:
      Mobile Phone Laptop VM at home  
      The folder names propably are different for non-German localized Windows and Dropbox, just modify them to meet your localization.
      DBox-Sync.au3
    • By TheDcoder
      Hello, it has been a long time since I have posted here
      I am working on an AutoIt project where I need to enable to user to interactively choose any point or coordinate on the screen... something like a big overlay where the user can click anywhere on the screen to select that point. @UEZ's screenshot tool may have something similar to what I need:
      I just checked the source code for the tool and I see that the Mark_Area function has a part in selecting the area to screenshot, I tried to figure out how it works but it is simply too complex and long...
      So I was wondering if there were any examples of interactively selecting points on a screen? Maybe an UDF that I can just use in my script to make the whole thing a matter of adding few lines
      Thank you for the replies in advance!
    • By Eggie6
      Hi all,
      I have a script 
      #include <IE.au3> Local $oIE = _IEAttach("anythinghere") $tags = $oIE.document.GetElementsByTagName("div") $oCollection = $oIE.document.getElementsByClassName("x-panel-btn-td") MsgBox(0, "", $oCollection.length) which shows 8 results, how can i see what those results are, and i need also to get ID of 4th in a row of them

      Please help
    • By kuhicop
      Hello, I'm trying to build some script with SplashImageOn, the idea is to show an image on top of the screen.
      But I don't know why it's not showing anything, I press "t" and nothing happens...
      #include <Date.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> HotKeySet("t","test") Global $title = "Time now: " & @HOUR & ":" & @MIN Global $image = "images\karanda0015.jpg" #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 615, 437, 192, 124) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Func test() If Not FileExists($image) Then MsgBox(16,"ERROR","Unable to find " & $image) EndIf SplashImageOn($title,$image,250,200,6,5) Sleep(5000) SplashOff() EndFunc While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch ;Loop() WEnd  
×
×
  • Create New...