Image output.
authorClaude Heiland-Allen <claude@mathr.co.uk>
Fri, 20 Dec 2013 20:37:50 +0000 (20:37 +0000)
committerClaude Heiland-Allen <claude@mathr.co.uk>
Fri, 20 Dec 2013 20:37:50 +0000 (20:37 +0000)
commitc71fb8b6c4775c6087fa23173a1613abefcb197a
treec5a7b0b2458b4c26ea16bf50a36d7ac4b8d3c963
parent024682465b9a56ec28bceb65e877d6e5636effcd
Image output.

The last image had curious speckles near the bottom, but our text-based
image resolution is too small to make them out properly.  It's also upside
down: mathematical convention dictates that complex numbers are visualized
with the imaginary part increasing in the upwards direction.  We can fix
the flip by negating the imaginary part when transforming from device
coordinates.

We want to create images with pixels instead of characters.  There are lots
of image formats out there, but one of the simplest is a family of related
formats called PNM, the ``portable anymap file format''.  We'll use the
portable graymap format PGM.  PGM files start with a text header, containing
metadata about the image.  First are the two characters P5 meaning ``this is
a PGM image'', followed by a blank space (typically a newline character).
Then come the width and height of the image, as decimal text, separated by
spaces.  The header ends with the ``maxval'' as decimal text, which is the
value that will represent white (zero represents black), followed by a single
newline character.  The header is then followed by the image data, in rows
from top to bottom with each row from left to right.  With a maxval of 255,
each pixel takes one byte.

We can increase the size to something a lot bigger than we had before, no
longer limited by our command line terminal width.  We no longer need to
adjust the aspect ratio because PNM formats have square pixels.  We can
use printf() for the image header text.  Because C treats bytes and
characters interchangably we can still use putchar(), but now we use
0 and 255 for a black and white image.  PNM formats have no separator between
rows (there is no need because the width is fixed by the header), so we
remove the one we output for text images.

Now our program writes image data, but our terminal expects text.  We
should ``redirect'' the output from our program to a file, so that we can
open it with an image viewer (such as ``display'' from the ImageMagick suite).
Command line shell redirection uses the ``>'' character to send the output
to a file (overwriting any pre-existing file, so be careful).  PGM files
usually have a .pgm extension.

    $ ./mandelbrot -0.75 0 1.25 > mandelbrot.pgm
    $ display mandelbrot.pgm

What's that blob on the left?

    $ ./mandelbrot -1.75 0 0.125 > mandelbrot.pgm
    $ display mandelbrot.pgm
    $ ./mandelbrot -1.76 0 0.03 > mandelbrot.pgm
    $ display mandelbrot.pgm

It looks like our original image of the whole Mandelbrot set.  What about
those speckles from before?

    $ ./mandelbrot -0.1 0.85 0.25 > mandelbrot.pgm
    $ display mandelbrot.pgm

They also look like (shrunken, rotated) copies of our original image of the
whole Mandelbrot set.
mandelbrot.c