On this page:
2.2.1 Basic Images
circle
ellipse
triangle
right-triangle
isosceles-triangle
square
rectangle
rhombus
regular-polygon
star
star-polygon
polygon
line
add-line
text
text/ font
bitmap
2.2.2 Overlaying Images
overlay
overlay/ align
overlay/ xy
beside
beside/ align
above
above/ align
2.2.3 Rotating, Scaling, and Framing Images
rotate
scale
scale/ xy
frame
2.2.4 Image Properties
image-width
image-height
image-baseline
2.2.5 Image Predicates
image?
mode?
color?
y-place?
x-place?
angle?
side-count?
2.2.6 Equality Testing of Images

2.2 Images: "image.ss"

 (require 2htdp/image)

The image teachpack provides a number of basic image construction functions, along with combinators for building more complex images out of existing images. Basic images include various polygons, ellipses and circles, and text, as well as bitmaps (typically bitmaps come about via the Insert Image... menu item in DrScheme). Existing images can be rotated, scaled, and overlaid on top of each other.

2.2.1 Basic Images

(circle radius mode color)  image?
  radius : (and/c real? (not/c negative?))
  mode : mode?
  color : color?
Constructs a circle with the given radius, height, mode, and color.

Examples:

  > (circle 30 "outline" "red")
  
  > (circle 20 "solid" "blue")
  

(ellipse width height mode color)  image?
  width : (and/c real? (not/c negative?))
  height : (and/c real? (not/c negative?))
  mode : mode?
  color : color?
Constructs an ellipsis with the given width, height, mode, and color.

Examples:

  > (ellipse 40 20 "outline" "black")
  
  > (ellipse 20 40 "solid" "blue")
  

(triangle side-length mode color)  image?
  side-length : (and/c real? (not/c negative?))
  mode : mode?
  color : color?
Constructs a upward-pointing equilateral triangle. The side-length argument determines the length of the side of the triangle.

Example:

  > (triangle 40 "solid" "tan")
  

(right-triangle side-length1    
  side-length2    
  mode    
  color)  image?
  side-length1 : (and/c real? (not/c negative?))
  side-length2 : (and/c real? (not/c negative?))
  mode : mode?
  color : color?
Constructs a triangle with a right angle where the two sides adjacent to the right angle have lengths side-length1 and side-length2.

Example:

  > (right-triangle 36 48 "solid" "black")
  

(isosceles-triangle side-length    
  angle    
  mode    
  color)  image?
  side-length : (and/c real? (not/c negative?))
  angle : angle?
  mode : mode?
  color : color?
Creates a triangle with two equal-length sides, of length side-length where the angle between those sides is angle. The third leg is straight, horizontally. If the angle is less than 180, then the triangle will point up and if the angle is more, then the triangle will point down.

Examples:

  > (isosceles-triangle 200 170 "solid" "seagreen")
  
  > (isosceles-triangle 60 30 "solid" "aquamarine")
  
  > (isosceles-triangle 60 330 "solid" "lightseagreen")
  

(square side-length mode color)  image?
  side-length : (and/c real? (not/c negative?))
  mode : mode?
  color : color?
Constructs a square.

Examples:

  > (square 40 "solid" "slateblue")
  
  > (square 50 "outline" "darkmagenta")
  

(rectangle width height mode color)  image?
  width : real?
  height : real?
  mode : mode?
  color : color?
Constructs a rectangle with the given width, height, mode, and color.

Examples:

  > (rectangle 40 20 "outline" "black")
  
  > (rectangle 20 40 "solid" "blue")
  

(rhombus side-length angle mode color)  image?
  side-length : (and/c real? (not/c negative?))
  angle : angle?
  mode : mode?
  color : color?
Constructs a four sided polygon with all equal sides and thus where opposite angles are equal to each other. The top and bottom pair of angles is angle and the left and right are (- 180 angle).

Examples:

  > (rhombus 40 45 "solid" "magenta")
  
  > (rhombus 80 150 "solid" "mediumpurple")
  

(regular-polygon side-length    
  side-count    
  mode    
  color)  image?
  side-length : (and/c real? (not/c negative?))
  side-count : side-count?
  mode : mode?
  color : color?
Constructs a regular polygon with side-count sides.

Examples:

  > (regular-polygon 50 3 "outline" "red")
  
  > (regular-polygon 40 4 "outline" "blue")
  
  > (regular-polygon 20 8 "solid" "red")
  

(star side-length mode color)  image?
  side-length : (and/c real? (not/c negative?))
  mode : mode?
  color : color?
Constructs a star with five points. The side-length argument determines the side length of the enclosing pentagon.

Example:

  > (star 40 "solid" "gray")
  

(star-polygon side-length    
  side-count    
  step-count    
  mode    
  color)  image?
  side-length : (and/c real? (not/c negative?))
  side-count : side-count?
  step-count : step-count?
  mode : mode?
  color : color?
Constructs an arbitrary regular star polygon (a generalization of the regular polygons). The polygon is enclosed by a regular polygon with side-count sides each side-length long. The polygon is actually constructed by going from vertex to vertex around the regular polgon, but skipping over every step-count verticies.

For examples, if side-count is 5 and step-count is 2, then this function produces a shape just like star.

Examples:

  > (star-polygon 40 5 2 "solid" "seagreen")
  
  > (star-polygon 40 7 3 "outline" "darkred")
  
  > (star-polygon 20 10 3 "solid" "cornflowerblue")
  

(polygon verticies mode color)  image?
  verticies : (listof posn?)
  mode : mode?
  color : color?
Constructs a polygon connecting the given verticies.

Examples:

  > (polygon (list (make-posn 0 0)
                   (make-posn -10 20)
                   (make-posn 60 0)
                   (make-posn -10 -20))
             "solid" "burlywood")
  
  > (polygon (list (make-posn 0 0)
                   (make-posn 0 40)
                   (make-posn 20 40)
                   (make-posn 20 60)
                   (make-posn 40 60)
                   (make-posn 40 20)
                   (make-posn 20 20)
                   (make-posn 20 0))
             "solid" "plum")
  

(line x1 y1 color)  image?
  x1 : real?
  y1 : real?
  color : color?
Constructs an image representing a line segment that connects the points (0,0) to (x1,y1).

Examples:

  > (line 30 30 "black")
  
  > (line -30 20 "red")
  
  > (line 30 -20 "red")
  

(add-line image x1 y1 x2 y2 color)  image?
  image : image?
  x1 : real?
  y1 : real?
  x2 : real?
  y2 : real?
  color : color?
Adds a line to the image image, starting from the point (x1,y1) and going to the point (x2,y2).

Examples:

  > (add-line (ellipse 40 40 "outline" "maroon")
              0 40 40 0 "maroon")
  
  > (add-line (ellipse 80 60 "outline" "darkolivegreen")
              (+ 40 (* 40 (cos (* pi 1/4))))
              (+ 30 (* 30 (sin (* pi 1/4))))
              (+ 40 (* 40 (cos (* pi 5/4))))
              (+ 30 (* 30 (sin (* pi 5/4))))
              "darkolivegreen")
  

(text string font-size color)  image?
  string : string?
  font-size : (and/c integer? (<=/c 1 255))
  color : color?
Constructs an image that draws the given string, using the font size and color.

Examples:

  > (text "Hello" 24 "olive")
  
  > (text "Goodbye" 36 "indigo")
  

(text/font string    
  font-size    
  color    
  face    
  family    
  style    
  weight    
  underline?)  image?
  string : string?
  font-size : (and/c integer? (<=/c 1 255))
  color : color?
  face : (or/c string? #f)
  family : (or/c 'default 'decorative 'roman 'script 'swiss 'modern 'symbol 'system)
  style : (or/c 'normal 'italic 'slant)
  weight : (or/c 'normal 'bold 'light)
  underline? : any/c
Constructs an image that draws the given string, using a complete font specification.

The face and the family combine to give the complete typeface. If face is available on the system, it is used, but if not then a default typeface based on the family is chosen. The style controls if the face is italic or not (under Windows and Mac OS X, 'slant and 'italic are the same), the weight controls if it is boldface (or light), and underline? determines if the face is underlined. For more details on these arguments, see font%, which ultimately is what this code uses to draw the font.

Examples:

  > (text/font "Hello" 24 "olive"
               "Gill Sans" 'swiss 'normal 'bold #f)
  
  > (text/font "Goodbye" 18 "indigo"
               #f 'modern 'italic 'normal #f)
  
  > (text/font "not really a link" 18 "blue"
               #f 'roman 'normal 'normal #t)
  

(bitmap bitmap-spec)
 
bitmap-spec = rel-string
  | id
Loads the bitmap specified by bitmap-spec. If bitmap-spec is a string, it is treated as a relative path. If it is an identifier, it is treated like a require spec and used to refer to a file in a collection.

Examples:

  > (bitmap icons/stop-16x16.png)
  
  > (bitmap icons/b-run.png)
  

2.2.2 Overlaying Images

(overlay i1 i2 is ...)  image?
  i1 : image?
  i2 : image?
  is : image?
Overlays all of its arguments building a single image. The first argument goes on top of the second argument, which goes on top of the third argument, etc. The images are all lined up on their upper-left corners.

Examples:

  > (overlay (rectangle 30 60 "solid" "orange")
             (ellipse 60 30 "solid" "purple"))
  
  > (overlay (ellipse 10 10 "solid" "red")
             (ellipse 20 20 "solid" "black")
             (ellipse 30 30 "solid" "red")
             (ellipse 40 40 "solid" "black")
             (ellipse 50 50 "solid" "red")
             (ellipse 60 60 "solid" "black"))
  

(overlay/align x-place y-place i1 i2 is ...)  image?
  x-place : x-place?
  y-place : y-place?
  i1 : image?
  i2 : image?
  is : image?
Overlays all of its image arguments, much like the overlay function, but using x-place and y-place to determine where the images are lined up. For example, if x-place and y-place are both "middle", then the images are lined up on their centers.

Examples:

  > (overlay/align "middle" "middle"
                   (rectangle 30 60 "solid" "orange")
                   (ellipse 60 30 "solid" "purple"))
  
  > (overlay/align "right" "bottom"
                   (rectangle 20 20 "solid" "silver")
                   (rectangle 30 30 "solid" "seagreen")
                   (rectangle 40 40 "solid" "silver")
                   (rectangle 50 50 "solid" "seagreen"))
  

(overlay/xy i1 x y i2)  image?
  i1 : image?
  x : real?
  y : real?
  i2 : image?
Constructs an image by overlaying i1 on top of i2 after shifting i2 over by x pixels to the right and y pixels down.

Examples:

  > (overlay/xy (rectangle 20 20 "outline" "black")
                20 0
                (rectangle 20 20 "outline" "black"))
  
  > (overlay/xy (rectangle 20 20 "solid" "red")
                20 20
                (rectangle 20 20 "solid" "black"))
  
  > (overlay/xy (rectangle 20 20 "solid" "red")
                -20 -20
                (rectangle 20 20 "solid" "black"))
  
  > (overlay/xy
     (overlay/xy (ellipse 40 40 "outline" "black")
                 10
                 15
                 (ellipse 10 10 "solid" "forestgreen"))
     20
     15
     (ellipse 10 10 "solid" "forestgreen"))
  

(beside i1 i2 is ...)  image?
  i1 : image?
  i2 : image?
  is : image?
Constructs an image by placing all of the argument images in a horizontal row, aligned along their top edges.

Example:

  > (beside (ellipse 20 70 "solid" "gray")
            (ellipse 20 50 "solid" "darkgray")
            (ellipse 20 30 "solid" "dimgray")
            (ellipse 20 10 "solid" "black"))
  

(beside/align y-place i1 i2 is ...)  image?
  y-place : y-place?
  i1 : image?
  i2 : image?
  is : image?
Constructs an image by placing all of the argument images in a horizontal row, lined up as indicated by the y-place argument. For example, if y-place is "middle", then the images are placed side by side with their centers lined up with each other.

Examples:

  > (beside/align "bottom"
                  (ellipse 20 70 "solid" "lightsteelblue")
                  (ellipse 20 50 "solid" "mediumslateblue")
                  (ellipse 20 30 "solid" "slateblue")
                  (ellipse 20 10 "solid" "navy"))
  
  > (beside/align "center"
                  (ellipse 20 70 "solid" "mediumorchid")
                  (ellipse 20 50 "solid" "darkorchid")
                  (ellipse 20 30 "solid" "purple")
                  (ellipse 20 10 "solid" "indigo"))
  
  > (beside/align "baseline"
                  (text "ijy" 18 "black")
                  (text "ijy" 24 "black"))
  

(above i1 i2 is ...)  image?
  i1 : image?
  i2 : image?
  is : image?
Constructs an image by placing all of the argument images in a vertical row, aligned along their left edges.

Example:

  > (above (ellipse 70 20 "solid" "gray")
           (ellipse 50 20 "solid" "darkgray")
           (ellipse 30 20 "solid" "dimgray")
           (ellipse 10 20 "solid" "black"))
  

(above/align y-place i1 i2 is ...)  image?
  y-place : y-place?
  i1 : image?
  i2 : image?
  is : image?
Constructs an image by placing all of the argument images in a vertical row, lined up as indicated by the x-place argument. For example, if x-place is "middle", then the images are placed above each other with their centers lined up.

Examples:

  > (above/align "right"
                 (ellipse 70 20 "solid" "gold")
                 (ellipse 50 20 "solid" "goldenrod")
                 (ellipse 30 20 "solid" "darkgoldenrod")
                 (ellipse 10 20 "solid" "sienna"))
  
  > (above/align "center"
                 (ellipse 70 20 "solid" "yellowgreen")
                 (ellipse 50 20 "solid" "olivedrab")
                 (ellipse 30 20 "solid" "darkolivegreen")
                 (ellipse 10 20 "solid" "darkgreen"))
  

2.2.3 Rotating, Scaling, and Framing Images

(rotate angle image)  image?
  angle : angle?
  image : image?
Rotates image by angle degrees in a counter-clockwise direction.

Examples:

  > (rotate 45 (ellipse 60 20 "solid" "olivedrab"))
  
  > (rotate 5 (rectangle 50 50 "outline" "black"))
  
  > (rotate 45
            (beside/align
             "center"
             (rectangle 40 20 "solid" "darkseagreen")
             (rectangle 20 100 "solid" "darkseagreen")))
  

(scale factor image)  image?
  factor : real?
  image : image?
Scales image by factor.

Examples:

  > (scale 2 (ellipse 20 30 "solid" "blue"))
  
  > (ellipse 40 60 "solid" "blue")
  

(scale/xy x-factor y-factor image)  image?
  x-factor : real?
  y-factor : real?
  image : image?
Scales image by x-factor horizontally and by y-factor vertically.

Examples:

  > (scale/xy 3
              2
              (ellipse 20 30 "solid" "blue"))
  
  > (ellipse 60 60 "solid" "blue")
  

(frame image)  image?
  image : image?
Returns an image just like image, except with a black, single pixel frame drawn around the bounding box of the image.

Example:

  > (frame (ellipse 20 20 "outline" "black"))
  

Generally speaking, this function is useful to debug image constructions, i.e., to see where certain sub-images appear within some larger image.

Example:

  > (beside/align "bottom"
                  (ellipse 20 70 "solid" "lightsteelblue")
                  (frame (ellipse 20 50 "solid" "mediumslateblue"))
                  (ellipse 20 30 "solid" "slateblue")
                  (ellipse 20 10 "solid" "navy"))
  

2.2.4 Image Properties

(image-width i)  (and/c number? positive?)
  i : image?
Returns the width of i.

Examples:

  > (image-width (ellipse 30 40 "solid" "orange"))
  30
  > (image-width (circle 30 "solid" "orange"))
  60
  > (image-width (beside (circle 20 "solid" "orange")
                         (circle 20 "solid" "purple")))
  80

(image-height i)  (and/c number? positive?)
  i : image?
Returns the height of i.

Examples:

  > (image-height (ellipse 30 40 "solid" "orange"))
  40
  > (image-height (circle 30 "solid" "orange"))
  60
  > (image-height (overlay (circle 20 "solid" "orange")
                           (circle 30 "solid" "purple")))
  60

(image-baseline i)  (and/c number? positive?)
  i : image?
Returns the distance from the top of the image to its baseline. Unless the image was constructed with text or text/font, this will be the same as its height.

Examples:

  > (image-baseline (text "Hello" 24 "black"))
  18.0
  > (image-height (text "Hello" 24 "black"))
  24.0
  > (image-baseline (rectangle 100 100 "solid" "black"))
  100
  > (image-height (rectangle 100 100 "solid" "black"))
  100

2.2.5 Image Predicates

This section lists predicates for the basic structures provided by the image library.

(image? x)  boolean?
  x : any/c
Determines if x is an image. Images are returned by functions like ellipse and rectangle and accepted by functions like overlay and beside.

Additionally, images inserted into a DrScheme window are treated as bitmap images, as are instances of image-snip% and bitmap%.

(mode? x)  boolean?
  x : any/c
Determines if x is a mode suitable for constructing images. It can be one of 'solid, "solid", 'outline, or "outline", indicating if the shape is filled in or not.

(color? x)  boolean?
  x : any/c
Determines if x represents a color. Both strings and symbols are allowed as colors. For example, "magenta", "black", 'orange, and 'purple are allowed. Colors are not case-sensitive, so "Magenta", "Black", 'Orange, and 'Purple are also allowed, and are the same colors as in the previous sentence.

If a color is not recognized, black is used in its place.

The complete list of colors is available in the documentation for color-database<%>.

(y-place? x)  boolean?
  x : any/c
Determines if x is a placement option for the vertical direction. It can be one of "top", 'top, "bottom", 'bottom, "middle", 'middle, "center", 'center, "baseline", or 'baseline.

The baseline of an image is the place where the bottoms any letters line up, not counting descenders, e.g. the tail on “y” or “g” or “j”.

(x-place? x)  boolean?
  x : any/c
Determines if x is a placement option for the horizontal direction. It can be one of "left", 'left, "right", 'right, "middle", 'middle, "center", or 'center.

(angle? x)  boolean?
  x : any/c
Determines if x is an angle, namely a real number between 0 (inclusive) and 360 (exclusive).

(side-count? x)  boolean?
  x : any/c
Determines if x is an integer greater than or equal to 3.

2.2.6 Equality Testing of Images

Image equality testing is done structurally, i.e., based on the construction of the image, although with certain, expected equivalences. For example, two rectangles with the same width, height, color, and mode are equal. Similarly, constructing a 20x10 rectangle and then rotating it by 90 degress is equal to a 10x20 rectangle (provided they have the same color and mode).

Equality testing may contain a few nuances, though:
  • Overlaying two images in opposite orders is never equal. For example, these two images are not equal:
      (overlay/xy (rectangle 30 10 "solid" "blue")
                  0
                  10
                  (rectangle 30 10 "solid" "red"))
      (overlay/xy (rectangle 30 10 "solid" "red")
                  0
                  -10
                  (rectangle 30 10 "solid" "blue"))
    even thought they may appear to be the same when drawn.

    The rationale for them being different is that, at some scale factor, they will draw differently; specifically when they are scaled down far enough, the first will appear to be a single red pixel and the second will appear to be a single blue pixel.

  • When rotating images, the internal calculations involve real numbers, not just rationals and thus must be approximated with Scheme’s inexact numbers, causing small roundoff errors that make the images draw slightly differently.

    To combat this problem, use equal~? to compare the images, or check-within for test suites involving images.

  • Combining a series of line segments to form a polygon produces an image that is different than the polygon.

  • In order to make equality on images created with text and text/font work well, each string passed to either of those functions results in a number of horizontally aligned images, one for each letter in the string. This means that, for example
      (equal? (beside/align "baseline"
                            (text "a" 18 "black")
                            (text "b" 18 "black"))
              (text "ab" 18 "black"))
    is true, but that subtle aspects of font drawing may be wrong, since the underlying toolkit only gets a single letter at a time, instead of the entire word (or sentence).

    The most obvious way that this shows up is in the handling of ligatures. For example, the letter combinations “ff” and “fi” and “fl” are generally drawn intertwined when they appear together, and thus an “f” drawn separately from an “i” looks different than the ligature “fi”. For example, here is how 24 point Times font looks when the word “refill” is drawn, first with ligatures and then without:

    .