%CustomEntities; %CourseEntities; %CommonEntities; ]>
Laboratory: Storing Images with Pixmaps Summary: In this laboratory, you will further explore the use of pixmaps to represent an image.
Preparation Add the preliminary versions of rgb-write and rgb-read to your definitions pane.
Exercises
Exercise 1: Reading and Writing Simple Colors a. Write the three primaries (red, green, blue), the three secondaries (cyan, magenta, and yellow), and black and white to the file some-colors.txt. That is, open a port to that file, write the colors using rgb-write, and then close the port. b. Open some-colors.txt and see if the numbers make sense. (If you open some-colors.txt in MediaScript, you'll need to make sure it's set to show all file types, and not just scheme files.) c. Using rgb-read, read back all the colors from the file, and verify that you have the same colors. For example, after opening the file and naming the port source, you might write > (define color (rgb-read source)) > (rgb->color-name color) > (rgb->string color)
Exercise 2: Reading and Writing Components a. Update the definitions of rgb-write and rgb-read so that they write each component separately. b. Write the three primaries, the three secondaries, and black and white to the file some-colors.txt. c. Open some-colors.txt and see if the numbers make sense. d. Using rgb-read, read back all the colors from the file, and verify that you have the same colors.
Exercise 3: Writing Code to Write Images a. Create an interesting 4x3 image. If you don't want to figure out an interesting image yourself, you can use the following set of commands. (define canvas (image-new 4 3)) (image-set-pixel! canvas 0 0 (rgb-new 0 0 255)) (image-set-pixel! canvas 0 1 (rgb-new 16 16 240)) (image-set-pixel! canvas 0 2 (rgb-new 32 32 224)) (image-set-pixel! canvas 1 2 (rgb-new 48 48 208)) (image-set-pixel! canvas 2 2 (rgb-new 64 64 192)) (image-set-pixel! canvas 3 2 (rgb-new 80 80 176)) (image-set-pixel! canvas 3 1 (rgb-new 96 96 160)) (image-set-pixel! canvas 3 0 (rgb-new 112 112 144)) b. Write that image to a file, using code similar to that in the reading. Here's a start. > (define pixmap (open-output-file "image1.pixmap")) > (rgb-write (image-get-pixel canvas 0 0) pixmap) > (rgb-write (image-get-pixel canvas 1 0) pixmap) > (rgb-write (image-get-pixel canvas 2 0) pixmap) > (rgb-write (image-get-pixel canvas 3 0) pixmap) > (rgb-write (image-get-pixel canvas 0 1) pixmap) > (rgb-write (image-get-pixel canvas 1 1) pixmap) ... ... ... > (close-output-port pixmap) c. What do you expect the file to contain? d. Open the file you've created and verify that it has the form you expected.
Exercise 4: Writing Images with <function>image-write-pixmap</function> a. Add image-write-pixmap to your definitions window. You can find the definition of this procedure at the end of the lab. b. Change the image from the previous exercise, using a command like > (image-transform! canvas rgb-complement) c. Using image-write-pixmap, write the modified image to the file image2.pixmap. d. What values do you expect that file to have? e. Verify that the file contains the values you were expecting.
Exercise 5: Reading Images a. Add image-read-pixmap to your definitions window. You can find the definition of this procedure at the end of the lab. b. Clear your current canvas. In GIMP, you can select all and then delete. You can also use the following commands, which do exactly the same thing. > (image-select-all! canvas) > (image-clear-selection! canvas) > (context-update-displays!) c. Using image-read-pixmap!, fill in the canvas from image1.pixmap d. Clear the canvas again. e. Using image-read-pixmap!, fill in the canvas from image2.pixmap
Exercise 6: Reading Into Other Size Images a. Create four new images --- canvas6x2, canvas3x4, canvas2x6, and canvas12x1 --- whose sizes match their names. b. What do you expect to have happen if we read from image1.pixmap into each of these images? c. Check your answer experimentally. d. Create two new images, canvas20x1 and canvas3x3, whose sizes match their names. e. What do you expect to have happen if we read from image1.pixmap into each of these images? f. Check your answer experimentally.
Exercise 7: Including the Image Size As the previous exercise suggests, one problem with the way we've chosen to store images in files is that we lose the size of the image. But without the size, the representation is not sufficient to restore the image. What can we do? We can first write the width and height of the image to the file. a. Rewrite image-write-pixmap so that it first writes the width and the height of the image to the file. b. Rewrite image-read-pixmap! so that it verifies that the image stored in the file is the same size as the given image. c. Write a new procedure, (image-read-pixmap filename), the takes as a parameter only a file name, reads the image size from the file, creates a new image of the appropriate size, and fills in the image from the file.
Exercise 8: Writing Pixmaps By Hand a. Create a file, image3.pixmap, with the following contents. 4 3 255 0 0 255 128 0 128 255 0 0 255 0 128 0 128 128 128 128 128 192 128 128 255 128 0 0 255 128 128 255 192 192 255 255 255 255 b. What do you expect to have happen if you load that file with your newly-written image-read-pixmap? c. Check your answer experimentally.
For Those With Extra Time
Extra 1: Reading Sections of Images Right now, when you read a pixmap into a larger image, it fills in the larger image, row-by-row, until you run out of colors. Instead, we could specify the section of the larger image to fill in. What should we specify? Presumably, the left edge, top edge, width, and height of the region to fill in. Write a procedure, (region-read-pixmap! image left top width height filename), that reads from a pixmap into a rectangular region in an image. For example, to read from a recently created pixmap file into the 4x3 section starting at 5,7, we might write > (region-read-pixmap! big-canvas 5 7 4 3 "image3.pixmap") Your procedure should verify that the width and height stored in the pixmap file match the width and height of the region. Your procedure should also verify that the region is completely contained in the image.
Extra 2: Writing Sections of Images If we're willing to read pixmaps into sections of images, we might as well provide the converse operation: Writing pixmaps from sections of images. Write a procedure, (region-write-pixmap image left top width height filename), that writes a region of an image to the specified file.
Explorations
Pick a reasonably small image of your choice and write it to a file with image-write-pixmap. See what effects you can obtain by reading that file into an image of a very different shape.
Useful Procedures