W1505 Images

From Coder Merlin
Revision as of 20:32, 19 February 2022 by Chukwuemeka-tinashe (talk | contribs) (→‎Exercises)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Within these castle walls be forged Mavens of Computer Science ...
— Merlin, The Coder
The Sun

Prerequisites[edit]

Research[edit]

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/


Start button green arrow
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.)

Hint.pngHelpful Hint
It's useful to bookmark this page in your browser.

Experiment[edit]

Stop button red ex
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:

  1. The Image must be initialized in init()
  2. The Image must be setup in setup()
  3. Then, if the Image is ready, we render it in render()
ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 1
  1. What do you think it means for an Image to be "ready"?
  2. 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.

Start button green arrow
Run the program and view in a browser before continuing.


ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 2
  1. What do you observe?
  2. What do you think determines the location of the image?
  3. What do you think determines the size of the image?

Positioning the Image[edit]

Stop button red ex
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)
        }
    }
Start button green arrow
Run the program and view in a browser before continuing.


ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 3
  1. What do you observe?

Resizing the Image[edit]

Stop button red ex
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)
        }
    }
Start button green arrow
Run the program and view in a browser before continuing.

Displaying a Portion of an Image[edit]

Stop button red ex
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)
        }
    }
Start button green arrow
Run the program and view in a browser before continuing.


ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 4
  1. What do you observe?
  2. What happens if the sourceRect is smaller than the destinationRect?
  3. What happens if the sourceRect is larger than the destinationRect?


CautionWarnIcon.png
Be careful to ensure that any URL you plan to use is truly a reference to a resource and not embedded data. It's very easy to determine which is which. A reference (in this case) will begin with either "http" or "https". A URL that begins with "data" actually contains inline data, not a reference to the source. In the case of some images this may be a very, very large amount of data. Attempting to paste this into a shell may cause the shell to hang. So it's very important to be sure that the URL begins with "http" or "https" BEFORE you paste.

Serving Images from the Merlin Server[edit]

Going DeeperGoingDeeperIcon.png

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]

ExercisesExercisesIcon.png
  •  J1505  Create a journal and answer all questions. Be sure to include all sections of the journal, properly formatted.
  1. 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.
  2. At least one of the images must be scaled up (i.e. it must be larger than the original source).
  3. At least one of the images must be scaled down (i.e. it must be smaller than the original source).
  4. At least one of the images must be only partially displayed (i.e. the source rectangle does not include the entire image).
  5. Draw a rectangular frame around each image. Each frame must be a different color.
  •  M1505-28  Complete  Merlin Mission Manager  Mission M1505-28.