/collects/teachpack/htdp/scribblings/image.scrbl

http://github.com/gmarceau/PLT · Racket · 314 lines · 238 code · 73 blank · 3 comment · 24 complexity · e1294bd5835975234b2f0b396248cd53 MD5 · raw file

  1. #lang scribble/doc
  2. @(require scribble/manual "shared.rkt" (for-label racket teachpack/htdp/image))
  3. @teachpack["image"]{Manipulating Images}
  4. @defmodule[#:require-form beginner-require htdp/image]
  5. The teachpack provides functions for constructing and manipulating
  6. images. Basic, colored images are created as outlines or solid
  7. shapes. Additional functions allow for the composition of images.
  8. @;-----------------------------------------------------------------------------
  9. @section{Images}
  10. @defproc[(image? [x any/c]) boolean?]{Is @racket[x] an image?}
  11. @defproc[(image=? [x image?] [y image?]) boolean?]{Are @racket[x] and
  12. @racket[y] the same image?}
  13. @;-----------------------------------------------------------------------------
  14. @section[#:tag "modes-colors"]{Modes and Colors}
  15. @deftech{Mode} @racket[(one-of/c 'solid 'outline "solid" "outline")]
  16. A @tech{Mode} is used to specify whether painting a shape fills or
  17. outlines the form.
  18. @defstruct[color [(red (and/c natural-number/c (<=/c 255)))
  19. (green (and/c natural-number/c (<=/c 255)))
  20. (blue (and/c natural-number/c (<=/c 255)))]]
  21. @deftech{RGB} @racket[color?]
  22. A @tech{RGB} describes a color via a shade of red, blue, and green colors
  23. (e.g., @racket[(make-color 100 200 30)]).
  24. @deftech{Color} @racket[(or/c symbol? string? color?)]
  25. A @tech{Color} is a color-symbol (e.g., @racket['blue]) or a color-string
  26. (e.g., @racket["blue"]) or an @tech{RGB} structure.
  27. @defproc[(image-color? [x any]) boolean?]{ Determines if the input is a
  28. valid image @tech{Color}.}
  29. @;-----------------------------------------------------------------------------
  30. @section[#:tag "creational"]{Creating Basic Shapes}
  31. In DrRacket, you can insert images from your file system. Use PNG images
  32. whenever possible. In addition, you can create basic
  33. shapes with the following functions.
  34. @defproc[(rectangle [w (and/c number? (or/c zero? positive?))] [h (and/c number? (or/c zero? positive?))] [m (unsyntax @tech{Mode})] [c (unsyntax @tech{Color})]) image?]{
  35. Creates a @racket[w] by @racket[h] rectangle, filled in according to
  36. @racket[m] and painted in color @racket[c]}
  37. @defproc[(circle [r (and/c number? (or/c zero? positive?))] [m (unsyntax @tech{Mode})] [c (unsyntax @tech{Color})]) image?]{
  38. Creates a circle or disk of radius @racket[r], filled in according to
  39. @racket[m] and painted in color @racket[c]}
  40. @defproc[(ellipse [w (and/c number? (or/c zero? positive?))] [h (and/c number? (or/c zero? positive?))] [m (unsyntax @tech{Mode})] [c (unsyntax @tech{Color})]) image?]{
  41. Creates a @racket[w] by @racket[h] ellipse, filled in according to
  42. @racket[m] and painted in color @racket[c]}
  43. @defproc[(triangle [s number?] [m (unsyntax @tech{Mode})] [c (unsyntax @tech{Color})]) image?]{
  44. Creates an upward pointing equilateral
  45. triangle whose side is @racket[s] pixels long, filled in according to
  46. @racket[m] and painted in color @racket[c]}
  47. @defproc[(star [n (and/c number? (>=/c 2))]
  48. [outer (and/c number? (>=/c 1))]
  49. [inner (and/c number? (>=/c 1))]
  50. [m (unsyntax @tech{Mode})]
  51. [c (unsyntax @tech{Color})]) image?]{
  52. Creates a multi-pointed star with @racket[n] points, an @racket[outer]
  53. radius for the max distance of the points to the center, and
  54. an @racket[inner] radius for the min distance to the center. }
  55. @defproc[(regular-polygon [s side] [r number?] [m (unsyntax @tech{Mode})] [c (unsyntax @tech{Color})] [angle real? 0]) image?]{
  56. Creates a regular polygon with @racket[s] sides inscribed in
  57. a circle of radius @racket[r], using mode @racket[m] and
  58. color @racket[c]. If an angle is specified, the polygon is rotated by that
  59. angle.
  60. }
  61. @defproc[(line [x number?][y number?] [c (unsyntax @tech{Color})]) image?]{
  62. Creates a line colored @racket[c] from (0,0) to @racket[(x,y)].
  63. See @racket[add-line] below.
  64. }
  65. @defproc[(text [s string?] [f (and/c number? positive?)] [c (unsyntax @tech{Color})]) Image]{
  66. Creates an image of the text @racket[s] at point size @racket[f]
  67. and painted in color @racket[c].}
  68. @;-----------------------------------------------------------------------------
  69. @section[#:tag "properties"]{Basic Image Properties}
  70. To understand how images are manipulated, you need to understand the
  71. basic properties of images.
  72. @defproc[(image-width [i image?]) integer?]{
  73. Obtain @racket[i]'s width in pixels}
  74. @defproc[(image-height [i image?]) integer?]{
  75. Obtain @racket[i]'s height in pixels}
  76. For the composition of images, you must know about @emph{pinholes}. Every
  77. image come with a pinhole. For images created
  78. with the above functions, the pinhole is at the center of the shape except
  79. for those created from @racket[line] and @racket[text].
  80. The @racket[text] function puts the pinhole at the upper left corner of
  81. the image, and @racket[line] puts the pinhole at the beginning of the line
  82. (meaning that if the first two arguments to @racket[line] are positive,
  83. the pinhole is also in the upper left corner).
  84. The pinhole can be moved, of course, and compositions
  85. locate pinholes according to their own rules. When in doubt you can always
  86. find out where the pinhole is and place it where convenient.
  87. @defproc[(pinhole-x [i image?]) integer?]{Determines the @racket[x]
  88. coordinate of the pinhole, measuring from the left of the image.}
  89. @defproc[(pinhole-y [i image?]) integer?]{Determines the @racket[y]
  90. coordinate of the pinhole, measuring from the top (down) of the image.}
  91. @defproc[(put-pinhole [i image?] [x number?] [y number?]) image?]{
  92. Creates a new image with the pinhole in the location specified by
  93. @racket[x] and @racket[y], counting from the left and top (down),
  94. respectively.}
  95. @defproc[(move-pinhole [i image?] [delta-x number?] [delta-y number?]) image?]{
  96. Creates a new image with the pinhole moved down and right by
  97. @racket[delta-x] and @racket[delta-y] with respect to its current
  98. location. Use negative numbers to move it up or left.}
  99. @;-----------------------------------------------------------------------------
  100. @section[#:tag "composition"]{Composing Images}
  101. Images can be composed, and images can be found within compositions.
  102. @defproc[(add-line [i image?]
  103. [x1 number?]
  104. [y1 number?]
  105. [x2 number?]
  106. [y2 number?]
  107. [c (unsyntax @tech{Color})]) image?]{
  108. Creates an image by adding a line (colored @racket[c]) from
  109. (@racket[x1],@racket[y1]) to
  110. (@racket[x2],@racket[y2])
  111. to image @racket[i].}
  112. @defproc[(overlay [img image?] [img2 image?] [img* image?] ...) image?]{
  113. Creates an image by overlaying all images on their pinholes.
  114. The pinhole of the resulting image is the same place as the pinhole in the
  115. first image.
  116. }
  117. @defproc[(overlay/xy [img image?] [delta-x number?] [delta-y number?] [other image?]) image?]{
  118. Creates an image by adding the pixels of @racket[other] to
  119. @racket[img].
  120. Instead of lining the two images up on their pinholes,
  121. @racket[other]'s pinhole is lined up on the point:
  122. @racketblock[
  123. (make-posn (+ (pinhole-x img) delta-x)
  124. (+ (pinhole-y img) delta-y))
  125. ]
  126. The pinhole of the resulting image is the same
  127. place as the pinhole in the first image.
  128. The same effect can be had by combining
  129. @racket[move-pinhole] and @racket[overlay],
  130. @racketblock[
  131. (overlay img
  132. (move-pinhole other
  133. (- delta-x)
  134. (- delta-y)))]
  135. }
  136. @defproc[(image-inside? [img image?] [other image?]) boolean?]{
  137. Determines whether the pixels of the second image appear in the first.
  138. Be careful when using this function with jpeg images. If you use an
  139. image-editing program to crop a jpeg image and then save it,
  140. @racket[image-inside?] does not recognize the cropped image, due to
  141. standard compression applied to JPEG images.}
  142. @defproc[(find-image [img image?] [other image?]) posn?]{
  143. Determines where the pixels of the second image appear in the first, with
  144. respect to the pinhole of the first image. If @racket[(image-inside? img
  145. other)] isn't true, @racket[find-image] signals an error.}
  146. @;-----------------------------------------------------------------------------
  147. @section[#:tag "manipulation"]{Manipulating Images}
  148. Images can also be shrunk. These ``shrink'' functions trim an image by
  149. eliminating extraneous pixels.
  150. @defproc[(shrink-tl [img image?][width number?][height number?]) image?]{
  151. Shrinks the image to a @racket[width] by @racket[height] image, starting
  152. from the @emph{top-left} corner. The pinhole of the resulting image is in
  153. the center of the image.}
  154. @defproc[(shrink-tr [img image?][width number?][height number?]) image?]{
  155. Shrinks the image to a @racket[width] by @racket[height] image, starting
  156. from the @emph{top-right} corner. The pinhole of the resulting image is in
  157. the center of the image.}
  158. @defproc[(shrink-bl [img image?][width number?][height number?]) image?]{
  159. Shrinks the image to a @racket[width] by @racket[height] image, starting
  160. from the @emph{bottom-left} corner. The pinhole of the resulting image is in
  161. the center of the image.}
  162. @defproc[(shrink-br [img image?][width number?][height number?]) image?]{
  163. Shrinks the image to a @racket[width] by @racket[height] image, starting
  164. from the @emph{bottom-right} corner. The pinhole of the resulting image is in
  165. the center of the image.}
  166. @defproc[(shrink [img image?][left number?][above number?][right number?][below number?]) image?]{
  167. Shrinks an image around its pinhole. The numbers are the pixels to save to
  168. left, above, to the right, and below the pinhole, respectively. The pixel
  169. directly on the pinhole is always saved.}
  170. @;-----------------------------------------------------------------------------
  171. @section[#:tag "scenes"]{Scenes}
  172. A @deftech{scene} is an image, but with the pinhole in the upper-left corner, i.e.
  173. an image where @racket[pinhole-x] and @racket[pinhole-y] both return
  174. @racket[0].
  175. Scenes are particularly useful with the
  176. @racketmodname[2htdp/universe] and @racketmodname[htdp/world]
  177. teachpacks, since it displays only @tech{scene}s in its canvas.
  178. @defproc[(scene? [x any/c]) boolean?]{Is @racket[x] an scene?}
  179. @defproc[(empty-scene [width natural-number/c]
  180. [height natural-number/c])
  181. scene?]{
  182. creates a plain white, @racket[width] x @racket[height] @tech{scene}.}
  183. @defproc[(place-image [img image?] [x number?] [y number?]
  184. [s scene?])
  185. scene?]{
  186. creates a scene by placing @racket[img] at
  187. @math{(@racket[x], @racket[y])} into @racket[s];
  188. @math{(@racket[x], @racket[y])} are computer graphics coordinates,
  189. i.e., they count right and down from the upper-left corner.}
  190. @defproc[(nw:rectangle [width natural-number/c] [height natural-number/c] [solid-or-outline Mode] [c Color]) image?]{
  191. creates a @racket[width] by @racket[height] rectangle, solid or outlined as specified by
  192. @racket[solid-or-outline] and colored according to @racket[c], with a pinhole at the upper left
  193. corner.}
  194. @defproc[(scene+line [s scene?][x0 number?][y0 number?][x1 number?][y1 number?][c Color]) scene?]{
  195. creates a scene by placing a line of color @racket[c] from
  196. @math{(@racket[x0], @racket[y0])} to @math{(@racket[x1],
  197. @racket[y1])} using computer graphics coordinates. In contrast to
  198. the @racket[add-line] function, @racket[scene+line] cuts off those
  199. portions of the line that go beyond the boundaries of the given
  200. @racket[s].}
  201. @;-----------------------------------------------------------------------------
  202. @section[#:tag "pixel-lists"]{Miscellaneous Image Manipulation and Creation}
  203. The last group of functions extracts the constituent colors from an image
  204. and converts a list of colors into an image.
  205. @defthing[List-of-color list?]{is one of:}
  206. @(begin
  207. #reader scribble/comment-reader
  208. (racketblock
  209. ;; -- @racket[empty]
  210. ;; -- @racket[(cons @#,tech{Color} List-of-color)]
  211. ;; Interpretation: represents a list of colors.
  212. ))
  213. @defproc[(image->color-list [img image?]) List-of-color]{
  214. Converts an image to a list of colors.}
  215. @defproc[(color-list->image [l List-of-color]
  216. [width natural-number/c]
  217. [height natural-number/c]
  218. [x natural-number/c]
  219. [y natural-number/c]) image?]{
  220. Converts a list of colors @racket[l] to an image with the given
  221. @racket[width] and @racket[height] and pinhole (@racket[x],@racket[y])
  222. coordinates, specified with respect to the top-left of the image.}
  223. The remaining functions provide alpha-channel information as well. Alpha
  224. channels are a measure of transparency; 0 indicates fully opaque and 255
  225. indicates fully transparent.
  226. @defstruct[alpha-color [(alpha (and/c natural-number/c (<=/c 255)))
  227. (red (and/c natural-number/c (<=/c 255)))
  228. (green (and/c natural-number/c (<=/c 255)))
  229. (blue (and/c natural-number/c (<=/c 255)))]]{
  230. A structure representing an alpha color.}
  231. @defproc[(image->alpha-color-list [img image?]) (list-of alpha-color?)]{
  232. to convert an image to a list of alpha colors}
  233. @defproc[(alpha-color-list->image
  234. [l (list-of alpha-color?)]
  235. [width integer?]
  236. [height integer?]
  237. [x integer?]
  238. [y integer?]) image?]{
  239. Converts a list of @racket[alpha-color]s @racket[l] to an image with the given
  240. @racket[width] and @racket[height] and pinhole (@racket[x],@racket[y])
  241. coordinates, specified with respect to the top-left of the image.}