Your task is to convert this:
into this:
An image is represented as a 2-dimensional array, just like the game of life simulation grid. As with ncurses, libnetpbm uses the y,x convention with the origin in the upper left corner.
For greyscale images, each element (pixel) of the grid is an intensity value, which is an integer usually between 0 and 255. The lower the intensity, the darker the pixel.
netpbm is a set of tools and a library for simple image processing. libnetpbm is the C library for reading, writing, and manipulating netpbm images.
netpbm images are one of three types: PBM (each pixel is either black or
white), PGM (greyscale), and PPM (color). Other types of images with which you
might be familiar include JPEG, PNG, or GIF; for libnetpbm to work with these
non-netpbm images you must convert them to the appropriate type. You can use
the convert
program which is a part of the
ImageMagick toolkit, or you can use the netpbm
tools. I recommend using convert
, like this:
convert foo.jpg foo.pgm
Because color images involve three values per pixel (red, green, and blue), it is simpler to work with greyscale images (PGM). For your convenience you can download this PGM image of the moon to work with.
To display PGM images, use the program display
which is also part of
ImageMagick, like so:
display foo.pgm
This will only work in the graphical environment in the lab. If you have
trouble with that, try converting to a JPEG with convert
and looking at it
with your web browser or favorite image-viewing program.
Unfortunately, the libnetpbm documentation is somewhat difficult to read and has a downright incorrect example, so I have written a PGM reference that you can refer to.
Making a negative of a greyscale image is simple enough. Intensity 0 becomes
intensity 255 (black becomes white), and vice versa. Intensity 1 becomes
intensity 254, and vice versa. Etc. The mathematical equation is new_intensity
= max_intensity - old_intensity
.
Write a program that takes a PGM file on stdin and writes a PGM file which is the negative of that image on stdout. Your program should run like this:
./negative < moon.pgm > moon-negative.pgm
Graduate students should work with color images (PPM) instead of grayscale. You will use the corresponding ppm functions, e.g. ppm_init
, ppm_readppm
, etc. as documented in the libppm manual. Taking a negative of a color image means inverting the intensity of red, green, and blue in each pixel. In actuality can can get more complicated than that, but that will be good enough.
To get and set the red, green, and blue values you will use the macros PPM_GETR
, PPM_GETG
, PPM_GETB
, and PPM_ASSIGN
, which are documented in the libppm manual.
Your program will run like this:
./negative < lena.ppm > lena-negative.ppm
I have converted two standard images to ppm format for you: Lena and Mandrill.
The end result should look something like this: