Resume Biography Gallery Digital Images Projects
Josh Grant
 
Master's Thesis
IVTrace
Creating 2D Images
Filter Functions
3D Elastic Collisions
3D Grapher
Open Inventor
Programming Tools
BoundingBox
ExaminerViewerPlus
MarchingCubes
ScalarArithmitic
SFScalarField
Courses
Photo-Realistic 2002
Visualization 2001
Photo-Realistic Computer Graphics
Intro to Computer Graphics
Scientific Visualization
 
Creating 2D Images
May 2001

Learning something new is usually most difficult in the beginning. However, once the initial fear is overcome and the basics are understood the learning becomes easier. This is true for computer graphics. At first computer graphics can seem a little overwhelming, but if you look at the basics it isn't that bad.

The main topics to be discussed are... This page is not devoted to revealing all the mysteries of programming computer graphics, it is mearly an introduction to the basics. 3D computer graphics will not be discussed, only the creation of 2D images. No special API like OpenGL is needed to run the code below, just the standard C++ libraries. It is assumed that the reader has an itermediate level of C++ programming experience. The code provided below was written in C++ using classes and dynamic memory allocation.

2D Images

It is important to understand how 2D images are generated before diving into 3D interactive scenes. Mainly because everything viewed with a computer monitor is in 2D. Some images look 3D, but they are actually just 2D. Think of the monitor as just one giant 2D image. The monitor is made up of an array of pixels, and each is assigned a particular color. The colors are made up of 3 different values, a Red component, Green component, and a Blue component (RGB). Each component is simply an unsigned char value in the range [0..255]. This is all the information needed to create and write a color image in 2D!

The below code can be used to represent all the above using C++.
// used to contain color information about each pixel
class Pixel {
  unsigned char  red;
  unsigned char  green;
  unsigned char  blue;

                 Pixel    ();
  void           setPixel (unsigned char r,
                           unsigned char g,
			   unsigned char b)
  {
    red   = r;
    green = g;
    blue  = b;
  };
};

...

Pixel image[800][600];
The above is not the best way to represent an image, but it would work. Now the image just needs to be saved in a format readable by an image viewer.

Writing PPM Files

One of the easiest formats to store images in is the Portable PixMap (PPM) file format. It isn't readable by Netscape, unless the proper plug-in is installed. Kevin Kurtz wrote a PPM viewer plug-in for Netscape on Windows and can be downloaded here. xv on the UNIX platform will read PPM files.

A PPM file can be either written in ASCII text or binary format. Better explainations for reading and writing PPM files can be found by searching the internet, but below is a quick example.
P3
# my PPM file
4 3
15
  0   0   0    0   0   0    0   0   0
  0   0   0    0 100   7    0   0   0
  0   0   0    0   0   0    0 100   9
100   0 100    0   0   0    0   0   0
The header contains the keyword "P3" which signifies an ASCII PPM file, a comment started with a '#' character, the image dimensions, and the total number of colors the image contains.

Image Domains

Once individual pixels can be easily modified and an image can be written to file, it is time to become slightly more advanced. Instead of referencing each pixel by a pair of integer values it is better to create an image domain using floating point values which are then mapped back to integer pairs. For example, if the image is 200x100 (pixels), then the image domain may be (0.0..2.0, 0.0..1.0). Now an infinite number of points can be referenced from the image (of course there are still a finite number of pixels). One of the main goals behind creating these image domains is so create nicer images. This might seem unnecessary now, but if this can be useful when creating anti-aliased images.

Coordinate Systems

The coordinate system used the most in computer graphics is the Rectangular system with X and Y axes. However, often in a 3D scene it is necessary to apply a texture to a surface. If the surface is a sphere then a Spherical system with with S (theta) and T (phi) axes can be used.

The Image Class

The Image class was written to create an image with a desired domain and set points within the domain to a color. The Image class contains public member functions to assign a color to an individual point, or draw a dot centered at a point. When drawing a dot, the user specifies the center point, color, radius and filter function to be applied to the dot. Drawing dots instead of setting points often greatly reduces the number of samples required to render a scene (provided the proper radius and filter function are chosen).

The drawdot Program

drawdot was written as a driver for the Image class. Its standard usage with out any arguments will create an image with a single dot at the origin and output a binary formatted image to stdout. However, drawdot is also equipped with several command line options.
Usage : drawdot [-file name] [-size x,y] [-color r,g,b]
                [-point x,y,z] [-rad n] [-filter 1..5]
		[-random num]

Options:
  -file   name  : Name of file to save image to,
                  default=STDOUT
  -size   x,y   : dimensions of image in pixels,
                  default=200x200
  -color  r,g,b : Color of dot to be drawn,
                  default=random color
  -point  x,y,z : Point in image domain to be drawn,
                  default=origin
  -rad    n     : Radius of dot, same units as image
                  domain, default=0.5
  -filter 1..5  : Filter to be applied to dot.
                  1 = BOX
                  2 = TENT
                  3 = QUADRATIC
                  4 = CUBIC
                  5 = QUARTIC
                  default=TENT
  -random num   : When this argument is set, num randomly
                  positioned, filtered, colored, and sized
		  dots are drawn.

Creating Animations

Creating an animation is really not complicated at all. An animation is just a series of images displayed at a constant rate. With this basic definition in mind the drawdot program can be used to create some simple animations. drawdot was set up with command line arguments to position a dot at any point within the image domain, along with any radius, color, and filter. A script can very easily be written to drive the drawdot program to generate an animation.

Below are examples of gif animations with links to the Perl scripts used to create them. The first is a single dot bouncing within the image domain, the second is a single dot with its radius expanding and shrinking, and the third is a single dot changing from red to purple to blue and then in reverse. All of them were created by calling drawdot a specified number of times, converting the images to gifs using ppmtogif and then using gifmerge to generate the animation. (ppmtogif and gifmerge are available on most UNIX sytems and souce code can be found on Google relatively quickly.)

bounce.pl
 
grow.pl
 
change.pl

Code

All the code used to create the above images and animations is provided below. Links to the individual files are available as well as a link to a tar file containing all files and scripts.
 

Josh Grant > Projects > Creating 2D Images

Comments or questions about this page can be addressed to Josh Grant at grant@cs.fsu.edu