CSC151.01 2009F Functional Problem Solving : Labs

Laboratory: Scripting the GIMP Tools


Summary: In this laboratory, you will explore how one writes Scheme programs that instruct the GIMP to create some simple images.

Preparation

a. Start GIMP.

b. Start MediaScript by selecting the Xtns menu, then the MediaScript menu item, and finally, Console.

c. At the end of this lab is a list of all the important procedures discussed in the corresponding reading. Quickly review that list.

Exercises

Exercise 1: Simple Faces

Here are the instructions for drawing a simple face from the reading.

(define smiley (image-new 200 200))
(image-show smiley)

; Draw the primary circle
(image-select-ellipse! smiley REPLACE 
                       10 10 180 180)
(context-set-fgcolor! "yellow")
(image-fill-selection! smiley)

(context-set-fgcolor! "black")
(context-set-brush! "Circle (09)")
(image-stroke-selection! smiley)

; Draw the eyes
(image-select-ellipse! smiley REPLACE 
                       50 60 30 20)
(image-select-ellipse! smiley ADD
                       120 60 30 20)
(context-set-fgcolor! "white")
(image-fill-selection! smiley)

(context-set-fgcolor! "black")
(context-set-brush! "Circle Fuzzy (07)")
(image-stroke-selection! smiley)

(image-select-ellipse! smiley REPLACE
                       60 60 10 20)
(image-select-ellipse! smiley ADD
                       130 60 10 20)
(context-set-fgcolor! "lightsteelblue")
(image-fill-selection! smiley)

; Smile
(image-select-ellipse! smiley REPLACE 
                       40 60 120 100)
(image-select-ellipse! smiley SUBTRACT
                       40 45 120 100)
(context-set-fgcolor! "white")
(image-fill-selection! smiley)

(context-set-fgcolor! "red")
(context-set-brush! "Calligraphic Brush#3")
(image-stroke-selection! smiley)

; Get ready to show
(image-select-nothing! smiley)
(context-update-displays!)

a. Copy these instructions into your definitions pane. Read through the instructions to see what image you predict they will draw.

b. Click Run and observe what happens. If all has gone well, you should see a new image with a smiling face.

c. In your interactions window, write instructions for drawing a nose onto the image. Your instructions might look something like the following:

> (image-select-rectangle! smiley REPLACE 90 90 20 20)
> (image-select-ellipse! smiley INTERSECT 80 85 30 30)
> (context-set-fgcolor! "green")
> (image-fill-selection! smiley)

If the instructions don't seem to change the image, try clicking on the image window or typing (context-update-displays!).

d. It is possible to clear an image by selecting everything and then clearing the selection. Do so now.

> (image-select-all! smiley)
> (image-clear-selection! smiley)
> (context-update-displays!)

e. Sometimes it's more fun to see an image drawn little-by-little. MediaScript allows you to pause a bit between actions, as when you want to show each step in the creation of a drawing. In particular, the procedure (usleep n) pauses for n microseconds. Hence, if you want to pause for a half a second, you might write (usleep 500000).

Edit the instructions in the definitions pane as follows. Immediately after each call to image-fill-selection! and image-stroke-selection!, insert instructions to update the displays and then sleep half a second. (Hint: Type the instructions once, then use copy and paste.)

Run your modified code.

Exercise 2: Drawing Faces, Revisited

a. Open a new MediaScheme window and write a series of instructions in the definitions pane to draw a face different than the sample we gave above. You should try a different shape of face, different brushes or colors, and different facial features.

b. What do you expect to happen if you change the size of the image in which you're drawing, such as a 100x100 image or a 300x300 image?

c. Check your answer experimentally.

d. If changing the size of the image yielded results that you found undesirable, summarize how you might fix them. (Don't fix them right now, just indicate how you might fix them.)

Exercise 3: Drawing Houses

a. Write a series of instructions that create a new image and then draw a house in in the image.

b. Suppose we start by defining two names, width and height. Describe how you might change your house code to take those values into account.

(define width 300)
(define height 200)
(define canvas (image-new width height))
...

Exercise 4: Modifying Existing Images

Suppose we've defined picname as a string naming an image.

(define picname "/home/rebelsky/glimmer/samples/rebelsky-stalkernet.jpg")

a. Write a series of instructions to load and show the picture.

b. Write a series of instructions to draw a diagonal line from the upper-left-hand-corner to the lower-right-hand corner of the image. Note that you'll need to use image-width and image-height to determine the width and height of the image.

c. Write a series of instructions to put some kind of border at the edges of the image. (E.g., select a rectangle ten pixels from each edge and then stroke that rectangle.)

For Those with Extra Time

Extra 1: Generalizing smiley faces

Revise your instructions from Exercise 2 so that the drawing adapts to the size of the image.

Recall that you can obtain the width and height of the image using the image-width and image-height procedures.

Reference

(image-new width height)
MediaScheme GIMP Procedure. Create a new image of specified width and height.
(image-load filename)
MediaScheme GIMP Procedure. Load an image from a file. The name of the file is a string (and, unless a named value, typically surrounded by quotation marks).
(image-show image)
MediaScheme GIMP Procedure. Opens a new window with the image.
(image-blot! image col row)
MediaScheme GIMP Procedure. Draw a spot in image at (col,row) with the current brush and foreground color.
(image-draw-line! image col1 row1 col2 row2)
MediaScheme GIMP Procedure. Draw a line in image from (col1,row1) to (col2,row2). Uses the current brush and foreground color.
(image-select-ellipse! image selection-type left top width height)
MediaScheme GIMP Procedure. Select an ellipse whose left margin is left, top margin is top, width is width and height is height. If selection-type is REPLACE, the ellipse replaces the current selection. If selection-type is ADD, the ellipse is added to the current selection. If selection-type is SUBTRACT, the ellipse is subtracted from the current selection. If selection-type is INTERSECT, the ellipse is intersected with the current selection (that is, only points that are in both the current selection and the ellipse remain selected).
(image-select-rectangle! image selection-type left top width height)
MediaScheme GIMP Procedure. Select an rectangle whose left margin is left, top margin is top, width is width and height is height. If selection-type is REPLACE, the rectangle replaces the current selection. If selection-type is ADD, the rectangle is added to the current selection. If selection-type is SUBTRACT, the rectangle is subtracted from the current selection. If selection-type is INTERSECT, the rectangle is intersected with the current selection (that is, only points that are in both the current selection and the rectangle remain selected).
(image-select-all! image)
MediaScheme GIMP Procedure. Selects all of the pixels in the image.
(image-select-nothing! image)
MediaScheme GIMP Procedure. Clears the current selection. Afterwards, nothing is selected.
(image-fill-selection! image)
MediaScheme GIMP Procedure. Fill the selected region of the given image with the current foreground color.
(image-stroke-selection! image)
MediaScheme GIMP Procedure. Traces the edge of the selected region of the given image with the current brush and foreground color.
(context-set-brush! brush-name)
MediaScheme GIMP Procedure. Sets GIMP's current brush to brush-name.
(context-set-fgcolor! color)
MediaScheme GIMP Procedure. Sets GIMP's current foreground color to color.
(context-list-brushes)
MediaScheme GIMP Procedure. List all valid brush names.
(context-list-brushes pattern)
MediaScheme GIMP Procedure. List all the valid brush names that contain pattern.
(context-update-displays!)
MediaScheme GIMP Procedure. Update all of the displays to show changes to images.
(usleep usec)
Optional Scheme Procedure. Pause for usec microseconds.

Creative Commons License

Samuel A. Rebelsky, rebelsky@grinnell.edu

Copyright (c) 2007-9 Janet Davis, Matthew Kluber, Samuel A. Rebelsky, and Jerod Weinman. (Selected materials copyright by John David Stone and Henry Walker and used by permission.)

This material is based upon work partially supported by the National Science Foundation under Grant No. CCLI-0633090. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.

This work is licensed under a Creative Commons Attribution-NonCommercial 2.5 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/2.5/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.