W1505 Images
Prerequisites[edit]
Research[edit]
- Read Bitmaps
- Read Raster Graphics
Prepare[edit]
Create a new Scenes shell project within your Experiences directory:
ty-cam@codermerlin:~$ cd ~/Experiences
ty-cam@codermerlin:~/Experiences$ git clone https://github.com/TheCoderMerlin/ScenesShellBasic W1505
Enter the Sources/ScenesShell directory of the new project:
ty-cam@codermerlin:~/Experiences$ cd W1505/Sources/ScenesShell/
![]() |
Run the program.
ty-cam@codermerlin:~/Experiences/W1505/Sources/ScenesShell$ run |
Ensure that you are logged on to the wiki. Then, click on the Tools menu followed by right-clicking on IGIS and selecting the menu item Open in New Window or Open in New Tab.
You'll know you're successful if you see the title bar change to "Coder Merlin: IGIS". (The browser window will be blank because we haven't added any graphics yet.)

Experiment[edit]
![]() |
Stop the running program.
Return to the console and press CONTROL-C |
Basic Images[edit]
Images enable us to render precomposed graphics from a specified URL. There are three required steps to rendering an image:
- The Image must be initialized in init()
- The Image must be setup in setup()
- Then, if the Image is ready, we render it in render()

- What do you think it means for an Image to be "ready"?
- Why didn't we need to wait for a Path or an Ellipse to be ready?
Open the file Background.swift in emacs.
We need to include the Foundation library (because we're using URLs. Add it at the top of the file:
import Foundation
import Scenes
import Igis
Add a new property to the Background class:
class Background : RenderableEntity {
let whitehouse : Image
init() {
// Using a meaningful name can be helpful for debugging
super.init(name:"Background")
}
}
Update init() to create both the URL and then use that URL to create the Image:
class Background : RenderableEntity {
let whitehouse : Image
init() {
guard let whitehouseURL = URL(string:"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/US-WhiteHouse-Logo.svg/2000px-US-WhiteHouse-Logo.svg.png") else {
fatalError("Failed to create URL for whitehouse")
}
whitehouse = Image(sourceURL:whitehouseURL)
// Using a meaningful name can be helpful for debugging
super.init(name:"Background")
}
}
At this point, we've created the image object and specified the URL, but we haven't yet informed the browser to load the image. We do that in the setup() method. Add a new method (below init) as follows:
override func setup(canvasSize:Size, canvas:Canvas) {
canvas.setup(whitehouse)
}
setup() will inform the browser load the image. But we haven't yet told the browser to display the image. We do that in render() method. Add that method (below setup() and edit so that it appears as follows:
override func render(canvas:Canvas) {
if whitehouse.isReady {
canvas.render(whitehouse)
}
}
The conditional ensures that the image is ready for display prior to issuing the request to the browser to display it.
Remember to save the file, then suspend emacs.
![]() |
Run the program and view in a browser before continuing. |

- What do you observe?
- What do you think determines the location of the image?
- What do you think determines the size of the image?
Positioning the Image[edit]
![]() |
Stop the running program.
Return to the console and press CONTROL-C |
We can position the Image by specifying a different topLeft. Let's move the Image to (x:100, y:200). Edit the render method as follows:
override func render(canvas:Canvas) {
if whitehouse.isReady {
whitehouse.renderMode = .destinationPoint(Point(x:100, y:200))
canvas.render(whitehouse)
}
}
![]() |
Run the program and view in a browser before continuing. |

- What do you observe?
Resizing the Image[edit]
![]() |
Stop the running program.
Return to the console and press CONTROL-C |
The image is rather large. We can resize the image by displaying it in a rect, which will include both the position and size. Edit the render method as follows:
override func render(canvas:Canvas) {
if whitehouse.isReady {
whitehouse.renderMode = .destinationRect(Rect(topLeft:Point(x:100, y:200), size:Size(width:300, height:200)))
canvas.render(whitehouse)
}
}
![]() |
Run the program and view in a browser before continuing. |
Displaying a Portion of an Image[edit]
![]() |
Stop the running program.
Return to the console and press CONTROL-C |
Finally, rather than display the entire image, we can opt to display just a portion, as specified by a source rect. The image from the source rect will be scaled and displayed in the destination rect. Edit the render method as follows:
override func render(canvas:Canvas) {
if whitehouse.isReady {
let sourceRect = Rect(topLeft:Point(x:740, y:400), size:Size(width:532, height:495))
let destinationRect = Rect(topLeft:Point(x:100, y:200), size:Size(width:266, height:247))
whitehouse.renderMode = .sourceAndDestination(sourceRect:sourceRect, destinationRect:destinationRect)
canvas.render(whitehouse)
}
}
![]() |
Run the program and view in a browser before continuing. |

- What do you observe?
- What happens if the sourceRect is smaller than the destinationRect?
- What happens if the sourceRect is larger than the destinationRect?

Serving Images from the Merlin Server[edit]

It's sometimes useful to be able to display images from a GitHub project. (You'll learn more about this later.). In order to do so: 1. Create a link from your GitHub project to your www directory:
john-williams@codermerlin:~/www$ ln -s /home/john-williams/Experiences/FavoriteProject/Images favorite-project-images
2. Set the permissions for each directory leading to your images:
john-williams@codermerlin:~$ chmod a+rx Experiences
john-williams@codermerlin:~$ chmod a+rx Experiences/FavoriteProject
3. Set the permissions for the image directory and all images:
john-williams@codermerlin:~$ chmod -R a+rX Experiences/FavoriteProject/Images
Exercises[edit]

- J1505 Create a journal and answer all questions. Be sure to include all sections of the journal, properly formatted.
- Think of a theme for your composition. Add at least four different images to your canvas following your chosen theme. (You may remove the White House.) Remember to only use images that are licensed appropriately. The images may not overlap.
- At least one of the images must be scaled up (i.e. it must be larger than the original source).
- At least one of the images must be scaled down (i.e. it must be smaller than the original source).
- At least one of the images must be only partially displayed (i.e. the source rectangle does not include the entire image).
- Draw a rectangular frame around each image. Each frame must be a different color.
- M1505-28 Complete Merlin Mission Manager Mission M1505-28.