This tutorial, as you may have guessed, shows you how to create a repeating sequence of images – a slideshow.
So that it looks a little less boring, we'll use Cobra's alpha blend (transparency) abilities to fade in the images one after the other. Also, to cut down on memory usage, we'll only load the images as and when we use them; doing this will show you how to step through a directory and pick out only the required file types.
The first thing we need to do is tell Cobra what modules we want to use, as well as declare our variables.
Uses Pure2D, Keyset
scrW : Integer = 800
scrH : Integer = 600
dir : Element
nf : String
delay : Integer = 6000
ms : Integer
fImg, bImg, tImg : Element
trans : Element
scale : Real
quit : Boolean = FALSE
Here we're creating a normal Program
, using the Pure2D
and Keyset modules, as well defining (and in some cases, setting the values of) our variables.
(the width and height that we will open our graphics screen at) have been defined here due to us needing those values several times in the program. If we want to change this later, we'll now only have to change this value in one place.
is the ID for our directory and nf
is a string that will hold the name of the next file in the directory.
are timing values that we'll use to regulate the speed of the slideshow.
are image buffers. tImg
is the buffer an image is initially loaded into. This is done because we are going to scale the image before displaying it. This needs to be done as the original image may be too large to fit on the screen (e.g. in the case of a high resolution photo) and so we'll only be able to see a small area of it. We will also scale up any image that is smaller than the screen in order to be able to see it more clearly.
is a flag that will be set to TRUE
when the user wants to exit the program. Although a Boolean variable is always set to FALSE
by default, it is generally good practice never to assume what a variable should be set to simply because you have declared it.
fImg = CreateImage(scrW, scrH)
bImg = CreateImage(scrW, scrH)
trans = CreateTransform
After beginning the main section of our program, a screen is opened and two image buffers are created; bImg
will hold the last image that was loaded in, while fImg
will hold the freshly loaded image that will be faded in. Both of these buffers are set to the same size as the graphics screen.
is our transformation matrix, and will be used to scale the loaded images as necessary. Don’t worry if that sounds complicated; Cobra transformations enable you to scale, rotate and distort images as you see fit, but you’ll be glad to know that the maths that do the actual scaling are handled by Cobra. See the tutorial on transformations for more information.
While quit = FALSE
dir = OpenDir('*.jpg', CFA_READONLY)
nf = NextFile(dir)
This is outer loop of our main program. The program will return to this point every time the directory with our slideshow images has run out of images to display. Opening the directory from scratch resets the file pointer, so the slideshow will actually loop back to the beginning. The program will stay in this loop until quit
is given a value of TRUE
is used to open the directory the program is running in and to only take notice of jpeg images (*.jpg)
The first use of NextFile
retrieves the filename of the first jpeg image in the directory and stores it in the variable nf
While (nf <> '') and (quit = FALSE)
tImg = LoadImage(nf)
Our next loop. The program will stay within this loop as long as there is still another valid image to display in the directory and as long as the user doesn’t want to exit the slideshow (quit = FALSE)
While (nf <> ‘’)
is what actually checks there is another image to load; we’re checking if the previous call to NextFile
actually managed to retrieve a filename. If it didn’t, nf
won’t contain anything.
does just that and loads in an image using the filename in nf
scale = ToReal(scrW)/ImageWidth(tImg)
If ToReal(ImageHeight(tImg))*scale > scrH Then scale = ToReal(scrH)/ImageHeight(tImg)
Because the images in a slideshow can’t all be assumed to be the same size, we need to resize each image after loading it. If the image is larger than our graphics screen, then it needs to be shrunk so all of the image is visible; if it’s smaller than the screen, then it needs to be enlarged. Well, actually it doesn’t need
to be enlarged, but since the above calculation works out the scale factor in either direction, we’ll go with it anyway.
To resize the image, we use Cobra’s transformation routines. Before we can tell Cobra by what factor to scale our image, we obviously need to work out how much it needs to be scaled; a small bit of maths is involved, but nothing complicated.
The first of the above two lines uses the horizontal size of the image against the screen width to work out our initial scale factor; in other words we divide the width of the graphics screen (scrW
) by the width of the image to be displayed (tImg
As we need a real (floating point) number for the scaling transformation, we have to take into account Cobra’s rules regarding maths. Because scrW
is an integer (whole number), Cobra would normally return an integer answer (the type of the first variable in a calculation sets the type of the returned value for that calculation), so we use the ToReal
command to ensure we get a real value returned.
We now have a scale factor that will either stretch or shrink the image to fine across the width of our graphics screen. However, due to us not being able to assume the general width/height ratio of any image that will be displayed, we need to check that the image isn’t taller than the height of the screen. The second of the above two lines does this and if it, sets the scale factor based on the height of the image instead of the width.
TransformScale(trans, scale, scale)
DrawTransform(tImg, trans, (scrWscale*ImageWidth(tImg))/2, (scrH-scale*ImageHeight(tImg))/2, fImg)
command clears our fImg
buffer. This is done due to the fact that our rescaled image may not be perfectly rectangular in order to fill the buffer entirely, and will probably have either a vertical or horizontal border. We therefore need to make sure any previous image is erased so that nothing of the previous image sneaks in.
tells Cobra to rescale our image using the scale factor we previously worked out. DrawTransform
then draws the rescaled tImg
buffer onto our fImg
buffer. The maths in that line simply work out the positioning so that tImg
is drawn centered on fImg
totally transparent, and since we now have our freshly rescaled image stored in fImg
, we can free the memory that the original image is taking up with FreeImage
ms = Millisecs
If ImageAlpha(fImg) < 255 Then ImageAlpha(fImg, ImageAlpha(fImg)+1)
If KeyDown(VK_ESCAPE) Then quit = TRUE
DrawImage(bImg, 0, 0)
DrawImage(fImg, 0, 0)
Until ((Millisecs > ms+delay) And (ImageAlpha(fImg) = 255)) or (quit = TRUE)
The third of our loops. Before we enter it though, we store the current milliseconds value from the PC’s internal clock in ms
. This will then be used to regulate the delay before the slideshow moves onto the next image. You may think "why not just use the Pause
command"? The problem if we do that is that the user will be left waiting if the escape key is pressed to exit the program, as we can't act upon the keypress if the program is suspended with Pause
The first line in the loop checks the alpha (transparency) value of our front image. If it’s less than 255
(255 being opaque) then we increase it’s value by one. You’ll notice how the ImageAlpha
command is used as a procedure to set this value while at the same time using ImageAlpha
again as a function in order to provide a parameter).
lets us see if the escape key has been pressed (VK_ESCAPE
) and if it has we change quit
The two DrawImage
commands draw our two image buffers. bImg
is the image before last (or just a black screen the first run through the loop), and then the alpha'd fImg
is drawn over the top to create the fading effect. Flip
displays the whole lot to the screen.
part of the loop regulates the delay between changing the images. For an image to change, we’ve specified that the current image must have finished fading in (ImageAlpha(fImg) = 255)
that a specified amount of time has passed (Millisecs > ms+delay
). Alternatively, if the user has pressed the escape key, therefore setting quit
equal to TRUE
, the loop will exit straight away.
DrawImage(fImg, 0, 0, bImg)
nf = NextFile(dir)
Now that the latest image transition has finished, the transformation matrix is cleared for the current image is copied onto the background image ready for the next image to be loaded. NextFile
then looks for the next applicable file for us to load and once again stores the filename in nf
Our second loop now comes to end, and it will exit here if there are no more files in the directory to display.
The open directory is closed so that when the program returns to the beginning of the main loop, the directory can be reopened, and the program will display all of the images from the beginning.
If the user has hit the escape key, then the program will exit our main loop at this Wend
We’re almost done! Although Cobra will automatically free up any images you may have loaded, it's polite to tidy up after yourself, so we free up the fImg
image buffers. Since tImg
is freed during every loop, there’s no need to do it here.
Last but not least, we shut down the graphics screen and end the program. There you go – one slideshow. Try changing the scrW
values that we set at the beginning of the program and you will see that any image loaded in is scaled correctly regardless of the resolution.
There are lots of ways to expand on this example; let the user changed the speed of the transition, alter the delay before moving to the next image, or even the ability to select various file types, but I’ll leave that up to you.
Click [url=tutorialmedia/slideshow_tutorial.zip]HERE[/url] to download the sourcecode for this tutorial.