Saving a Canvas

The canvas, by itself, is just an intermediate step. It might represent an image of your scene, but you can’t look at it directly. You can’t show it to anyone. You can’t use it to brag about how awesome your 3D-rendered scene looks, or how amazing your ray tracer is. To do that, you need to be able to take the information in your canvas and write it out to a file, which could then be viewed, emailed, tweeted, Instagrammed, or whatever.

Let’s make that happen.

You could choose from a lot of different image formats, but you’re only going to implement one of them: the Portable Pixmap (PPM) format from the Netpbm project.[9] There are several flavors of the PPM format, but the version you’ll implement (called “plain” PPM) is straight text.

Joe asks:
Joe asks:
How do I view a PPM file?

If you use a Mac, you’re in luck, because Preview.app (which is part of the OS) can open PPM files. From the finder, just double-click on the PPM file you want to view, or type open my-image.ppm from the command line.

The story is more complicated for Linux and Windows, but not terribly so. There are a lot of tools that you can get for either platform that will open PPM files, but you really can’t go wrong with the GNU Image Manipulation Program (GIMP).[10] It’s free, it’s cross-platform, it’s open-source, and it’s well-maintained.

Every plain PPM file begins with a header consisting of three lines of text. The following figure shows one possible header.

 P3
 80 40
 255

The first line is the string P3 (which is the identifier, or “magic number,” for the flavor of PPM we’re using), followed by a new line. The second line consists of two numbers which describe the image’s width and height in pixels. The header in the previous figure describes an image that is 80 pixels wide, and 40 tall. The third line (255) specifies the maximum color value, which means that each red, green, and blue value will be scaled to lie between 0 and 255, inclusive.

Write the following test. It introduces a function called canvas_to_ppm(canvas) which returns a PPM-formatted string. This test will help ensure that the header is created properly.

 Scenario​: Constructing the PPM header
 Given​ c ← canvas(5, 3)
 When​ ppm ← canvas_to_ppm(c)
 Then​ lines 1-3 of ppm are
 """
  P3
  5 3
  255
  """

Immediately following this header is the pixel data, which contains each pixel represented as three integers: red, green, and blue. Each component should be scaled to between 0 and the maximum color value given in the header (for example, 255), and each value should be separated from its neighbors by a space.

Add the following test to your suite to show that the PPM pixel data is constructed correctly for a canvas where three pixels have been colored. Note that color components that would be greater than 255 are limited (or clamped) to 255, and components that would be less than 0 are clamped to 0.

 Scenario​: Constructing the PPM pixel data
 Given​ c ← canvas(5, 3)
 And​ c1 ← color(1.5, 0, 0)
 And​ c2 ← color(0, 0.5, 0)
 And​ c3 ← color(-0.5, 0, 1)
 When​ write_pixel(c, 0, 0, c1)
 And​ write_pixel(c, 2, 1, c2)
 And​ write_pixel(c, 4, 2, c3)
 And​ ppm ← canvas_to_ppm(c)
 Then​ lines 4-6 of ppm are
 """
  255 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0 0 0 0 0 0 0 128 0 0 0 0 0 0 0
  0 0 0 0 0 0 0 0 0 0 0 0 0 0 255
  """

Notice how the first row of pixels comes first, then the second row, and so forth. Further, each row is terminated by a new line.

In addition, no line in a PPM file should be more than 70 characters long. Most image programs tend to accept PPM images with lines longer than that, but it’s a good idea to add new lines as needed to keep the lines shorter. (Just be careful to put the new line where a space would have gone, so you don’t split a number in half!)

Implement the following test to ensure that pixel data lines do not exceed 70 characters.

 Scenario​: Splitting long lines in PPM files
 Given​ c ← canvas(10, 2)
 When​ every pixel of c is set to color(1, 0.8, 0.6)
 And​ ppm ← canvas_to_ppm(c)
 Then​ lines 4-7 of ppm are
 """
  255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204
  153 255 204 153 255 204 153 255 204 153 255 204 153
  255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204
  153 255 204 153 255 204 153 255 204 153 255 204 153
  """

One more thing. Some image programs (notably ImageMagick[11]) won’t process PPM files correctly unless the files are terminated by a newline character. Add the following test to satisfy those picky consumers.

 Scenario​: PPM files are terminated by a newline character
 Given​ c ← canvas(5, 3)
 When​ ppm ← canvas_to_ppm(c)
 Then​ ppm ends with a newline character

That’s really all there is to PPM files. The next step is to wrap it all up with a bow and do something fun with it! Let’s revisit the program you wrote in the previous chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.183.89