These puzzles involve reading in a color image (or two) and writing out a new color image.
[M-50]
Write a program that swaps the colors in a color image.
The command line looks like:
C:\PuzzleFolder>swapColors original.ppm result.ppm XYZ
where X is the color that replaces red in the original, Y is the color that replaces green in the original, and Z is the color that replaces blue in the original. For example, GRB asks to swap the red channel and the green channel of the original. RRR asks to replace all channels of the original with its red channel. GBR asks to replace the red channel with the green channel, the green channel with the blue channel, and the blue channel with the red channel.
If a character is 0, then replace the corresponding color with black. For example G0R means to replace red with green, replace green with balck, and replace blue with red.
Before | After |
[E-10]
Write a program that creates a gray level image based on a color image
The command line looks like:
C:\PuzzleFolder>makeGray original.ppm gray.ppm
It would be sensible to create the gray level image as a pgm image, but for this puzzle create a ppm image. If you do that, the program can be used as a template for other programs. For each RGB pixel in the input image, compute the average of the three bytes and output that average for each of color of the pixel.
Color Image | Gray Level Image |
Here is a template for your program:
#include <stdlib.h> #include <stdio.h> #include "../basicColorImage.c" void toGray( colorImage cimg, colorImage gimg) { . . . . } int main ( int argc, char* argv[] ) { colorImage cimg; colorImage gimg; if ( argc != 3 ) { printf("PPMtoGrayPPM oldImage.ppm newImage.ppm\n"); system( "pause" ); exit( EXIT_FAILURE ); } /* read in the old image */ readPPMimage( &cimg, argv[1]); /* create empty color image */ if ( newColorImage( &gimg, cimg.nrows, cimg.ncols ) == NULL ) { printf(">>error<< newColorImage can't allocate memory\n"); exit( EXIT_FAILURE ); } /* fill in gray level image */ toGray( cimg, gimg ) ; /* write the image to disk and free memory */ writePPMimage( gimg, argv[2]); freeColorImage( &cimg ); freeColorImage( &gimg ); }
You may need to adjust the third #include
directive depending on where you put the include file.
[E-25]
Write a program that creates a new color image based on an input color image.
However, for all pixels with an average color level above (or below) a specified threshold, output
a gray pixel (each of RGB set to the average) rather than a color pixel.
The command line looks like:
C:\PuzzleFolder>makeGray original.ppm gray.ppm threshold above|below
The last parameter of the command line says if pixels above or below the threshold are to be output as gray.
Color Image | Pixels above 100 set to gray |
No answer is provided for this puzzle, but it should be and easy edit of the previous program.
[E-25]
Write a program that creates a new color image based on an input color image
by adding fixed values of RBG to each pixel
The command line looks like:
C:\PuzzleFolder>brighten original.ppm bright.ppm red green blue
If red, green, and blue are all the same value, then this adds white to the image. The image will look washed out. If they are different values, the image will take on a cast of whatever two colors are largest. Of course, you will have to watch out for pixel values that exceed the value 255. The RGB values can be negative, so watch out for pixel values below zero.
Color Image | Brightened with 25 40 50 |
[E-25]
Write a program that inputs a gray level PGM image and outputs a gray level PPM image.
This might seem like a silly thing to do, but the output image will be useful with other program.
The command line looks like:
C:\PuzzleFolder>PGMtoPPM original.pgm output.ppm
[E-25]
Write a program that inputs a gray level PPM image and outputs a PPM image where the gray levels
have been converted to sepia.
This make the picture look like an old time image.
Do this by a linear transformation of the range of input gray levels 0 to 255,
to the range (0, 0, 0) to (224, 132, 40).
The last color of this range is bright sepia.
Calculate the gray level of a pixel as the average of its RGB values.
The command line looks like:
C:\PuzzleFolder>makeSepia original.ppm sepia.ppm [red green blue]
The last three parameters are optional and specify the color that gray level 255 should be transformed into. For example, the achieve the same effect as the default, the last three parameters should be 224, 132, 40.
Gray Image | Converted to default Sepia Tones |
(Image from Wikipedia.)
[E-25]
Write a program that creates a new image half the size of an input image.
The command line looks like:
C:\PuzzleFolder>halfColor original.ppm halfSize.ppm
Halve the image by outputing every other pixel of every other row. (In other words skip every other row. Within a row not skipped, output every other pixel.) For a smoother effect, regard the input image as made of two by two blocks of pixels. Output the average color of each block.
Full Size | Half Size |
[E-25]
Write a program that creates a new image twice the size of an input image.
The command line looks like:
C:\PuzzleFolder>twiceColor original.ppm doubleSize.ppm
For each pixel of the original image, output a two by two block the color of that pixel. Of course, this will produce a blocky effect. To reduce the blockieness, regard the output image as made of two by two block. The upper left corner of each block gets the color of the corresponding pixel in the input image. The upper right corner of each block gets the average color of horizontally adjacent pixels of the input image. The lower left corner gets the average color of vertically adjacent pixels of the input image. The lower left corner gets the average color of the diagonally adjacent pixels in the input image. See puzzle 38 for a diagram of this. Of course, for this puzzle, you will have to average color values.
Full Size | |
Twice Size |
[M-90]
Write a program that automatically adjusts the color of an image.
The command line looks like:
C:\PuzzleFolder>autoColor original.ppm adjusted.ppm
To automatically adjust the color values of the pixels of an image, do this:
There may be problems with this. One problem is that noise might introduce a bright pixel with RGB values that don't represent the image. To overcome this problem, scan through the image looking for the brightest 3x3 region. (For real noisy images, increase the size of the region.) Now use the average RBG values of that region as MaxRed, MaxGreen, and MaxBlue.
Another problem is that adjusting pixel values might create values greater than 255. Clamp RBG values at 255, as usual. A third problem is that using regions instead of pixels means that you need to be careful with borders. Details, details... But that is what programing is about.
Original | Color Adjusted |
My program for this is only 90 lines long. I was surprised at how well it did with the above image. Sadly, you will have to write this program yourself, since the answer is not provided. But the other programs of this section have already done most of what you need.
[E-90]
Write a program that inputs a color image and writes three gray level images,
one per color.
Now the gray level images can be manipulated with the programs from the gray level
section and later combined back into a color image.
The command line looks like:
C:\PuzzleFolder>channels -s original.ppm red.pgm green.pgm blue.pgm
The command line for the choice that combines channels into a color image is:
C:\PuzzleFolder>channels -c combined.ppm red.pgm green.pgm blue.pgm
Original | Red Channel |
Green Channel | Blue Channel |
This program is not too hard, but useful.