These puzzles involve the image
structure discussed in Images
in memory.
[E-10]
Write a main()
program with
a command line that lists a file name, image rows and columns, and a gray level.
Create a PGM image file of that name with all of its pixels that gray level.
For example,
C:\PuzzleFolder>makeGray gray240.pgm 200 300 240
creates a gray level image file called gray240.pgm
of size 200
rows by 300 columns with all pixels at level 240. Here is the image the above
command line creates:
gray240.pgm |
This is the same as Puzzle 01, but now make use of the image
struct and the functions
newImage()
freeImage()
setPixel()
getPixel()
writePGMimage()
Here is a skeleton program that does most of the work. If you have a programming environment running (such as Bloodshed Dev-c++) use copy-and-paste to copy this code into a source file.
#include <stdio.h> #include <stdlib.h> #include "basicImage.c" /* remove this line if you are creating a project out of several files */ int main ( int argc, char* argv[] ) { image img ; int r, c; int nrows, ncols, value; if ( argc != 5) { printf("constImage fileName nrows ncols const\n"); return EXIT_SUCCESS; } /* convert parameters to int */ nrows = atoi( argv[2] ); ncols = atoi( argv[3] ); value = atoi( argv[4] ); . . . more stuff goes here . . . writePGMimage( img, argv[1]); freeImage( &img ); }
Finish the program by adding some lines to main()
. When you are
done, click on the answer icon to see a suggested answer. You may wish to improve
the program by checking that the parameters make sense.
[E-10]
Write a main()
program with
a command line that lists a file name, image rows and columns, and a gray level.
Call a function that creates an image with all of its pixels that gray level.
For example,
C:\PuzzleFolder>makeGrayRev2 gray240.pgm 200 300 240
creates a gray level image file called gray240.pgm
of size 200
rows by 300 columns with all pixels at level 240.
This program is the same as Puzzle 11, except now main()
calls
a function
void clearImage( image img, const unsigned char val)
which sets each pixel of an image struct to the same value. Many of the puzzles
I01 to I10 can be redone using the image
struct.
[E-10]
Write a program that creates a PGM image
file where the gray levels of the rows gradually increase from a minimum gray
level (in row 0) to a maximum gray level (in the last row). The pixels in each
row are all the same gray level. The program will have to pick a gray level
for each row based on row number
Puzzle 03 was similar to this, but it wrote pixels to the image file one by one. The command line for this program looks like:
C:\PuzzleFolder>makeIncrease imageName.pgm nrows ncols minGray maxGray
Here is an example image, where the gray levels start at 100 and ends at 200:
wedgeImageTwo.pgm |
[E-10]
Write a program that creates an image where
each pixel has a value randomly selected from a range of values. The command
line for this program looks like:
C:\PuzzleFolder>makeRandom imageName.pgm nrows ncols minGray maxGray
Create the image in raster order and for each pixel randomly selecting a value.
Use the function randInt(int min, int max)
from puzzle B05 for
selecting the random value. Here is an image where the random pixels are in
the range 100 to 200:
randomImage.pgm |
Initialize the random number generator using
srand( time(NULL) )
[M-10]
Write a function that alters the pixels
of an image in memory. The function will replace each pixel of the image with
the average of that pixel and the three pixels directly underneath it. If the
pixel is pixel(row, col), then the average is
avg = ( pixel(row, col) + pixel(row+1, col) + pixel(row+2, col) pixel(row+3, col) ) / 4
This will have the effect of streaking the image vertically. The streak function prototype is:
void streakVertical( image img );
Write a main program that first creates an image of random
pixels (just as in the previous puzzle)
then streaks it using this new function.
Initialize the random number generator using
srand( time(NULL) )
.
The command line parameters to the program will be
the same as before:
C:\PuzzleFolder>makeStreak imageName.pgm nrows ncols minGray maxGray
The minGray and maxGray values are for the random pixel function. Here is a streaked image where the random pixels are in the range 100 to 200:
streakImage.pgm |
The image looks smoother than the previous image of raw random pixels. Notice that the last three rows of the image are unstreaked. In the loops that compute average, be careful not to access pixels that are not there. One way to do this is to not streak the last three rows.
Image generation functions other than the random pixel image function can be used to create the un-streaked image. And later on, this function can be used with an image read in from a disk file.
[M-15]
Write a function that alters the pixels
of an image in memory. The function will replace each pixel of the image with
the maximum of that pixel and the three pixels to its right. If the pixel
is pixel(row, col), then the pixel is replaced by
maximum( pixel(row, col), pixel(row, col+1), pixel(row, col+2), pixel(row, col+3) )
This will have the effect of streaking the image horizontally, but with a different kind of streaking than above. The streak function prototype is:
void streakMax( image img );
Write a main program that first creates an image of random
pixels (just as in the previous puzzles)
then streaks it using this new function.
Initialize the random number generator using
srand( time(NULL) )
.
The command line parameters to the program will be
the same as before:
C:\PuzzleFolder>streakMax imageName.pgm nrows ncols minGray maxGray
The minGray and maxGray values are for the random pixel function. Here is a streaked image where the random pixels are in the range 100 to 175:
streakMaxImage.pgm |
For extra fun, create a random image, then streak it vertically, and then streak it horizontally. You can create some nice textures for web page backgrounds this way.
Create an image that is one gray level above the diagonal and another gray level on or below it. The command line parameters are the name and size of the image and the two gray levels. For example,
C:\PuzzleFolder>makeDiagonal diagonal.pgm 300 300 100 200
creates the following image:
diagonal.pgm |
Write the program as main()
or as a separate function.
[M-10]
Create an image that contains a solid circle
of one gray level on a background of another. The command line parameters should
be:
C:\PuzzleFolder>makeCircle imageName.pgm nrows ncols radius background foreground
For example,
C:\PuzzleFolder>makeCircle diagonal.pgm 300 300 100 100 200
creates the following image:
solidCircle.gif |
Write the program as main()
or as a separate function.
Create an image that is one gray level above the diagonal and another color on or below it. However, inside a centered circle the gray levels are reversed. The command line parameters are the name and size of the image, the two gray levels, and the radius. For example,
C:\PuzzleFolder>diagonalCircle diagonalCircle.pgm 300 300 100 200 100
creates the following image:
diagonalCircle.pgm |
Use nearly the same main()
as the previous program. Make a few
small changes in the parameters and in the function call.
Create an image that is one gray level above the diagonal and another color on or below it.
Now randomly pick about 25% of pixels of the image. If a pixel lies inside a centered circle of a particular radius, change its grey level to the other gray level. The command line parameters are the name and size of the image, the two gray levels, and the radius. For example,
C:\PuzzleFolder>diagonalRandomCircle diagonalRCircle.pgm 300 300 100 200 100
creates the following image:
diagonalRCircle.pgm |
Use nearly the same main()
as the previous program. You will need
to use the rand()
function.
Write a program that creates an image that has centered, circular ripples. The command line parameters are the size of the image and the
C:\>makeRipples ripples.pgm nrows ncols nripples
For example,
C:\>makeRipples ripples.pgm 300 300 5
creates the image:
ripples.pgm |
Ripples are made by calculating the gray level of a pixel based on its distance
from the center of the image. Say that dist
is that distance, halfDiag
is half the length of the diagonal of the image, and nripples
is
the number of ripples you want. Then the gray level is:
gray = 128 + 127*cos( 2*M_PI*nripples*dist/halfDiag );
The cos function varies between -1 and +1. When it is -1, the above expression
gives (127-127), or 0. When the cos is +1, the above expression gives 127+127,
or 254. The cos goes through one complete cycle in 2Π
radians. To get N complete cycles, we need 2NΠ
radians. These
are spread out over over halfDiag
. A pixel at row n
is at 2NΠ(n/halfDiag)
radians.
The definition of pi, M_PI
, is found in math.h. Not all C environments
support this. You may have to inspect your compiler options if it complains
about this constant.
Write a program that creates an image that has centered, circular ripples, as with the previous program. But now the gray level of a pixel is randomly picked from the range 0..max, where max depends on distance. The command line parameters are as before
C:\>makeRandomRipples ripples.pgm nrows ncols nripples
For example,
C:\>makeRandomRipples ripples.pgm 300 300 5
creates the image:
ripplesRandom.pgm |
This is can be done with a very small change to the previous program. You will
need to use rand()
, srand()
and the modulo operator,
%
.
Write a
program that creates an image with a filled circle of
a given radius placed at a particlar location. Use a subroutine to do this:
void drawCircle( image img, int row, int col, int radius, unsigned char value )
If the circle does not fit completely within the image, draw those pixels that are within the image and ignore the rest (be careful not to crash!). The command line looks like:
circleImage fileName nrows ncols backGroundGray circleRow circleCol circleRadius circleGray
Where circleRow
and circleCol
give the location of
the center of the circle. For example, the command
C:\PuzzleFolder>circleImage circleOffCenter.pgm 300 400 150 100 150 150 240
creates the image:
Here is the main()
program:
int main ( int argc, char* argv[] ) { image img ; int nrows, ncols, bgvalue; int crow, ccol, radius, fgvalue ; if ( argc != 9) { printf("circleImage fileName nrows ncols value"); printf(" circleRow circleCol circleRadius circleGray\n"); system( "pause" ); return EXIT_SUCCESS; } nrows = atoi( argv[2] ); ncols = atoi( argv[3] ); bgvalue = atoi( argv[4] ); crow = atoi( argv[5] ); ccol = atoi( argv[6] ); radius = atoi( argv[7] ); fgvalue = atoi( argv[8] ); if ( newImage( &img, nrows, ncols ) == NULL ) { printf(">>error<< memory allocation failure \n"); return; } clearImage( img, bgvalue ); drawCircle( img, crow, ccol, radius, fgvalue ); writePGMImage( img, argv[1]); freeImage( &img ); }
(A professional-level main()
would have more error checking.)
Write a
program that creates an image that has many randomly
places circles of a fixed radius. The circles may overlap and are all the same
gray level. The command line looks like:
manyCircles fileName nrows ncols background foreground radius howMany
For example,
C:\PuzzleFolder>manyCircles circlesRand.pgm 300 500 120 250 25 12
creates the image:
This program can be created by editing the previous program, adding some statements
to main()
.
Write a
program that creates an image that has many randomly
places circles of a fixed radius. The circles may NOT overlap and are all the
same gray level. The command line looks like:
seperatedCircles fileName nrows ncols background foreground radius howMany
For example,
C:\PuzzleFolder>seperatedCircles circlesSeperated.pgm 300 500 120 250 25 12
creates the image:
This Puzzle s harder than the previous programs of this section. There are several problems to think about.