W1505 Images

From Coder Merlin
Within these castle walls be forged Mavens of Computer Science ...
— Merlin, The Coder

Prerequisites[edit]

Research[edit]

Experiment[edit]

Get Ready[edit]

Begin a new project:

Create an Igis shell project within your "project" directory.

cd ~/projects
git clone https://github.com/TangoGolfDigital/IgisShell IgisShell-Images

Enter into the Sources directory of the new project.

cd IgisShell-Images/Sources/IgisShell/

Build the project. (This may take some time.)

swift build

Open a browser (or use a new tab on an already-open browser). Go to the URL: http://www.codermerlin.com/users/user-name/dyn/index.html

NOTE: You MUST change user-name to your actual user name. For example, http://www.codermerlin.com/users/john-williams/dyn/index.html

You'll know your successful if you see the title bar change to "Coder Merlin: IGIS".

Basic Images[edit]

We'll first declare the image as a property of our Painter object. Then, we'll initialize it in the setup method.

Open main.swift in emacs.

emacs main.swift

We'll need to include the Foundation library, so let's import that at the top of the file (above "import Igis"). Edit so that the top of the file appears as follows:

import Foundation
import Igis

Find the definition of the Painter object and edit it so it appears as follows:

class Painter : PainterBase {

    let whitehouse : Image

    required 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)
    }

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. Edit that method so it appears as follows:

    override func setup(canvas:Canvas) {
        canvas.setup(whitehouse)
    }

After setup has executed, the browser will be informed to load the image. But we haven't yet told the browser to display the image. We do that in the update method. Add that method and edit so that it appears as follows:

    override func update(canvas:Canvas) {
        if whitehouse.isReady {
            canvas.paint(whitehouse)
        }
    }

The conditional ensures that the image is ready for display prior to issuing the request to the browser to display it.

Now, run the program and view in a browser before continuing.

We can position the image by specifying a different topLeft. Let's move the image to (x:100, y:200). Edit the update method as follows:

    override func update(canvas:Canvas) {
        if whitehouse.isReady {
            whitehouse.renderMode = .destinationPoint(Point(x:100, y:200))
            canvas.paint(whitehouse)
        }
    }

Now, run the program and view in a browser before continuing.

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 update method as follows:

    override func update(canvas:Canvas) {
        if whitehouse.isReady {
            whitehouse.renderMode = .destinationRect(Rect(topLeft:Point(x:100, y:200), size:Size(width:300, height:200)))
            canvas.paint(whitehouse)
        }
    }

Now, run the program and view in a browser before continuing.

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 update method as follows:

    override func update(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.paint(whitehouse)
        }
    }

Now, run the program and view in a browser before continuing.

Exercises[edit]

Warning icon.svg Warning: 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.

Continuing with this project:

  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.

Extended Exercises[edit]

  1. Add at least thirty eyelashes per eye by calculating the correct position and angle of each eyelash.