1 About This Teachpack
2 Installation
3 Functions from image.rkt and universe.rkt
4 New image functions
rotate-cw
rotate-ccw
rotate-180
crop-top
crop-bottom
crop-left
crop-right
show-it
reflect-vert
reflect-horiz
5 Pixel functions
5.1 Colors and pixels
name->color
get-pixel-color
5.2 Specifying the color of each pixel of an image
map-image
map3-image
build-image
change-to-color
real->int
5.3 Transparency
pixel-visible?
maybe-color?
map-masked-image
build-masked-image
6 Input and Output
with-input-from-string
with-output-to-string
with-input-from-file
with-output-to-file
with-input-from-url
with-io-strings
Version: 5.0.1.2

Picturing Programs Teachpack

Stephen Bloch

 (require (planet sbloch/picturing-programs))

1 About This Teachpack

Provides a variety of functions for combining and manipulating images and running interactive animations. It’s intended to be used with the textbook Picturing Programs.

2 Installation

If you’re reading this, you’ve probably already installed the teachpack successfully, but if you need to install it on a different machine, ...
  1. start DrScheme

  2. switch languages to “Use the language declared in the source” and click “Run”

  3. in the Interactions pane, type
      (require (planet sbloch/picturing-programs:2))

  4. after a few seconds, you should see the message

    Wrote file “picturing-programs.rkt” to installed-teachpacks directory.

  5. switch languages back to one of the HtDP languages, like Beginning Student

  6. either
    • in the Definitions pane, type
        (require installed-teachpacks/picturing-programs)
      or

    • from the Language menu, choose "Add Teachpack..." and select "picturing-programs.rkt"

  7. click "Run"

3 Functions from image.rkt and universe.rkt

This package includes all of the image teachpack and and the universe teachpack, so if you’re using this teachpack, don’t also load either of those. See the above links for how to use those teachpacks.

It also supersedes the older tiles and sb-world teachpacks, so if you have those, don’t load them either; use this instead.

This package also provides the following additional functions:

4 New image functions

(rotate-cw img)  image?
  img : image?
Rotates an image 90 degrees clockwise.

(rotate-ccw img)  image?
  img : image?
Rotates an image 90 degrees counterclockwise.

(rotate-180 img)  image?
  img : image?
Rotates an image 180 degrees around its center.

(crop-top img pixels)  image?
  img : image?
  pixels : natural-number/c
Chops off the specified number of pixels from the top of the image.

(crop-bottom img pixels)  image?
  img : image?
  pixels : natural-number/c
Chops off the specified number of pixels from the bottom of the image.

(crop-left img pixels)  image?
  img : image?
  pixels : natural-number/c
Chops off the specified number of pixels from the left side of the image.

(crop-right img pixels)  image?
  img : image?
  pixels : natural-number/c
Chops off the specified number of pixels from the right side of the image.

(show-it img)  image?
  img : image?
Returns the given image unaltered. Useful as a draw handler for animations whose model is an image.

(reflect-vert img)  image?
  img : image?
The same as flip-vertical; retained for compatibility.

(reflect-horiz img)  image?
  img : image?
The same as flip-horizontal; retained for compatibility.

5 Pixel functions

The above functions allow you to operate on a picture as a whole, but sometimes you want to manipulate a picture pixel-by-pixel.

5.1 Colors and pixels

(name->color name)  (or/c color? false/c)
  name : string?
Given a color name like "red", "turquoise", "forest green", etc., returns the corresponding color struct, showing the red, green, and blue components. If the name isn’t recognized, returns false.

(get-pixel-color x y pic)  color?
  x : natural-number/c
  y : natural-number/c
  pic : image?
Gets the color of a specified pixel in the given image. If x and/or y are outside the bounds of the image, returns black.

5.2 Specifying the color of each pixel of an image

(map-image f img)  image?
  f : (-> natural-number/c natural-number/c color? color?)
  img : image?
Applies the given function to each pixel in a given image, producing a new image the same size and shape. For example,
  (define (lose-red x y old-color)
    (make-color 0 (color-green old-color) (color-blue old-color)))
  
  (map-image lose-red my-picture)
produces a copy of my-picture with all the red leached out, leaving only the blue and green components.

  (define (apply-gradient x y old-color)
    (make-color (min (* 3 x) 255) 0 (min (* 3 y) 255)))
  
  (map-image apply-gradient my-picture)
produces a picture the same size and shape as my-picture, but with a smooth color gradient with red increasing from left to right and blue increasing from top to bottom.

A version of map-image for students who don’t know about structs yet. Each of the three given functions is assumed to have the contract
  num(x) num(y) num(r) num(g) num(b) -> num
For each pixel in the original picture, applies the three functions to the x coordinate, y coordinate, red, green, and blue components of the picture. The result of the first function is used as the red component, the second as green, and the third as blue in the corresponding pixel of the resulting picture.

For example,
  (define (zero x y r g b) 0)
  (define (same-g x y r g b) g)
  (define (same-b x y r g b) b)
  (map3-image zero same-g same-b my-picture)
produces a copy of my-picture with all the red leached out, leaving only the blue and green components.

  (define (3x x y r g b) (min (* 3 x) 255))
  (define (3y x y r g b) (min (* 3 y) 255))
  (map3-image 3x zero 3y my-picture)
produces a picture the same size and shape as my-picture, but with a smooth color gradient with red increasing from left to right and blue increasing from top to bottom.

(build-image width height f)  image?
  width : natural-number/c
  height : natural-number/c
  f : (-> natural-number/c natural-number/c color?)
Builds an image of the specified size and shape by calling the specified function on the coordinates of each pixel. For example,
  (define (fuzz pic)
    (local [(define (near-pixel x y)
              (get-pixel-color (+ x -3 (random 7))
                               (+ y -3 (random 7))
                               pic))]
      (build-image (image-width pic)
                   (image-height pic)
                   near-pixel)))
produces a fuzzy version of the given picture by replacing each pixel with a randomly chosen pixel near it.

(change-to-color new-color)
  (->* (natural-number/c natural-number/c) (color?) color?)
  new-color : (or/c string? color?)
Returns a constant-valued function suitable for use in map-image or build-image. The input to change-to-color may be either a color struct or a color name from the standard color-name database. For example,
  (map-image (change-to-color "turquoise") my-picture)
returns a picture with the same size, shape, and mask as my-picture, but all turquoise, while
  (build-image 50 30 (change-to-color (make-color 0 100 200)))
is equivalent to (rectangle 50 30 "solid" (make-color 0 100 200))

(real->int num)  integer?
  num : real?
Not specific to colors, but useful if you’re building colors by arithmetic. For example,
  (define (bad-gradient x y)
    (make-color (* 2.5 x) (* 1.6 y) 0))
  (build-image 50 30 bad-gradient)
  (define (good-gradient x y)
    (make-color (real->int (* 2.5 x)) (real->int (* 1.6 y)) 0))
  (build-image 50 30 good-gradient)
The version using bad-gradient crashes because color components must be exact integers. The version using good-gradient works.

5.3 Transparency

Some image formats support transparency, meaning that part of the image is ignored when layering it with other images.

(pixel-visible? x y pic)  boolean?
  x : natural-number/c
  y : natural-number/c
  pic : image?
Checks transparency: returns false if the specified pixel in the image is transparent, true if not.

A maybe-color is either a color or false, which is treated as transparent.

(maybe-color? thing)  boolean?
  thing : any/c
Tests whether the argument is a maybe-color.

(map-masked-image f pic)  image?
  f : (-> natural-number/c natural-number/c maybe-color? maybe-color?)
  pic : image?
Like map-image, but the function will receive false for any transparent pixel, and any place that it returns false will be treated as a transparent pixel.

(build-masked-image width height f)  image?
  width : natural-number/c
  height : natural-number/c
  f : (-> natural-number/c natural-number/c maybe-color?)
Like build-image, but any place that the function returns false will be treated as a transparent pixel.

6 Input and Output

This teachpack also provides several functions to help in testing I/O functions (in Advanced Student language; ignore this section if you’re in a Beginner or Intermediate language):

(with-input-from-string input thunk)  any/c
  input : string?
  thunk : (-> any/c)
Calls thunk, which presumably uses read, in such a way that read reads from input rather than from the keyboard.

(with-output-to-string thunk)  string?
  thunk : (-> any/c)
Calls thunk, which presumably uses display, print, write, and/or printf, in such a way that its output is accumlated into a string, which is then returned.

(with-input-from-file filename thunk)  any/c
  filename : string?
  thunk : (-> any/c)
Calls thunk, which presumably uses read, in such a way that read reads from the specified file rather than from the keyboard.

(with-output-to-file filename thunk)  any/c
  filename : string?
  thunk : (-> any/c)
Calls thunk, which presumably uses display, print, write, and/or printf, in such a way that its output is redirected into the specified file.

(with-input-from-url url thunk)  any/c
  url : string?
  thunk : (-> any/c)
Calls thunk, which presumably uses read, in such a way that read reads from the HTML source of the Web page at the specified URL rather than from the keyboard.

(with-io-strings input thunk)  string?
  input : string?
  thunk : (-> any/c)
Combines with-input-from-string and with-output-to-string: calls thunk with its input coming from input and accumulates its output into a string, which is returned. Especially useful for testing:
  (define (ask question)
    (begin (display question)
           (read)))
  (define (greet)
    (local [(define name (ask "What is your name?"))]
      (printf "Hello, ~a!" name)))
  (check-expect
   (with-io-strings "Steve" greet)
   "What is your name?Hello, Steve!")