Puzzle 81 - Puzzle 90

Color Images in Memory

These puzzles involve creating various three-color images. Now, the full images are kept in memory as they are processed.


Puzzle 81 — Color Chip in Memory

[E-10] Write a program that creates an image that is all one color. Unlike puzzle 61, create the image in memory and write it to disk when it is complete. The name of the image file, its size, and the red, green, and blue values are specified on the command line:

C:\PuzzleFolder>colorChip2  name.ppm numRows numCols red green blue

As before, color values are in the range 0 to 255. For example, the command

C:\PuzzleFolder>colorChip2  lightpurple.ppm 200 250 175 150 175

creates the image:

Light Purple

Here is most of the program, waiting for you to fill in the missing pieces:

#include <stdlib.h>
#include <stdio.h>
#include "../basicColorImage.c"

int getColor( int arg, char *argv[] )
{
  int value;
  value = atoi( argv[arg] );
  if ( value < 0 || value > 255 )
  {
    printf("color level %s  must be between 0 and 255\n", argv[arg]);
    exit( EXIT_FAILURE );
  }
  return value;
}

int main(int argc, char *argv[])
{
  int r, nrows, c, ncols, red, grn, blu;
  colorImage img ;
  pixel pix;

  /* check the command line parameters */
  if ( argc != 7 )
  {
    printf("colorChip2 fileName.ppm nrows ncols red green blue\n");
    return 0;
  }

  nrows = atoi( argv[2] );
  if ( nrows < 1 )
  {
    printf("number of rows must be positive\n");
    return 0;
  }

  ncols = atoi( argv[3] );
  if ( nrows < 1 )
  {
    printf("number of columns must be positive\n");
    return 0;
  }

  /* Get colors from the command line */
  pix.red = getColor( 4, argv );
  pix.grn = getColor( 5, argv );
  pix.blu = getColor( 6, argv );

  /* create the image structure */
  . . . .

  /* fill in the pixel data */
  . . . .

  /* write out the image */
  . . . .

  /* free memory */
  . . . .
}

Mostly this is an exercise in using the functions in basicColorImage.c.

 


Puzzle 82 — Image with Rectangles

[E-5] Write a function that places a rectangle of designated size and color at a designated location. The location of a rectangle is the row and column of its lower left corner. The pixel parameter holds the color with which to fill the rectangle.

void setRect( colorImage image, int row, int col, int height, int width, pixel pix);

Here is an example of an image with a few rectangles:

Three Rectangles

Here is a testing framework for your function:

#include <stdlib.h>
#include <stdio.h>
#include "../basicColorImage.c"

void setRect( colorImage image, int row, int col, int height, int width, pixel pix)
{
. . . .
}

int main(int argc, char *argv[])
{
  int r, nrows, c, ncols, red, grn, blu;
  colorImage img ;

  /* check the command line parameters */
  if ( argc != 4 )
  {
    printf("colorRectangles fileName.ppm nrows ncols\n");
    return 0;
  }

  nrows = atoi( argv[2] );
  if ( nrows < 1 )
  {
    printf("number of rows must be positive\n");
    return 0;
  }

  ncols = atoi( argv[3] );
  if ( nrows < 1 )
  {
    printf("number of columns must be positive\n");
    return 0;
  }

  /* create the image structure */
  if ( newColorImage( &img, nrows, ncols ) == NULL )
  {
    printf(">>error<< newColorImage can't allocate memory\n");
    return;
  }

  /* fill the image with light gray-green: */
  pixel pix = {175, 190, 175};
  for ( r=0; r<nrows; r++ )
    for ( c=0; c<ncols; c++ )
      setColorPixel( img, r, c, pix );

  /* put in a few rectangles */
  pixel p1 = {255, 0, 0};
  setRect( img, nrows/8, ncols/8, nrows/8, ncols/5, p1);

  pixel p2 = {0, 200, 150};
  setRect( img, nrows/3, ncols/4, nrows/4, ncols/4, p2);

  pixel p3 = {200, 200, 75};
  setRect( img, 5*nrows/7, 3*ncols/4, nrows/5, ncols/7, p3);

  /* write out the image */
  writePPMimage( img, argv[1] );

  /* free memory */
  freeColorImage( &img );
}

 


Puzzle 83 — Flood an Image with a Color

[E-15] Write a program based on the previous program. But now, create a function that fills an image with the designated color.

void fill( colorImage image, int red, int green, int blue);

All pixels of the image are set to the specified color. Pixels that are not black remain as they are. Also, write a function that floods an image with the designated color.

void flood( colorImage image, int red, int green, int blue);

All pixels of the image that are black are set to the specified color. Pixels that are not black remain as they are. Here is an example of an image before and after using flood():

Flooded Image

Here is a testing framework:

#include <stdlib.h>
#include <stdio.h>
#include "../basicColorImage.c"

void setRect( colorImage image, int row, int col, int height, int width, pixel pix)
{
. . . .
}

void flood( colorImage image, pixel pix)
{
. . . .
}

void fill( colorImage image, pixel pix)
{
. . . .
}

int main(int argc, char *argv[])
{
  int r, nrows, c, ncols, red, grn, blu;
  colorImage img ;

  /* check the command line parameters */
  if ( argc != 4 )
  {
    printf("fillAndFlood fileName.ppm nrows ncols\n");
    return 0;
  }

  nrows = atoi( argv[2] );
  if ( nrows < 1 )
  {
    printf("number of rows must be positive\n");
    return 0;
  }

  ncols = atoi( argv[3] );
  if ( nrows < 1 )
  {
    printf("number of columns must be positive\n");
    return 0;
  }

  /* create the image structure */
  if ( newColorImage( &img, nrows, ncols ) == NULL )
  {
    printf(">>error<< newColorImage can't allocate memory\n");
    return;
  }

  /* initialize the image to all black */
  pixel black = {0,0,0};
  fill( img, black );

  /* put in a few rectangles */
  pixel p1 = {255, 0, 0};
  setRect( img, nrows/8, ncols/8, nrows/8, ncols/5, p1);

  pixel p2 = {0, 200, 150};
  setRect( img, nrows/3, ncols/4, nrows/4, ncols/4, p2);

  pixel p3 = {200, 200, 75};
  setRect( img, 5*nrows/7, 3*ncols/4, nrows/5, ncols/7, p3);

  /* flood the image to light blue */
  pixel blue = {200,200,255};
  flood( img, blue );

  /* write out the image */
  writePPMimage( img, argv[1] );

  /* free memory */
  freeColorImage( &img );
}

 


Puzzle 84 — Color Circle

[E-5] Write a function that places a circle, of designated color and radius, at a location in the image. The location of a circle is the location of its radius. This function is an easy variation of puzzle I23. It is somewhat harder if you do it from scratch.

void drawColorCircle( colorImage image, int row, int col, int radius, pixel pix);

Here is a sample image:

Color Circles

Here is a testing framework:

#include <stdlib.h>
#include <stdio.h>
#include "../basicColorImage.c"

/* Draw a circle in the image */
void drawColorCircle( colorImage img, int row, int col,
                      int radius, pixel pix )
{
 ...
}

void fill( colorImage image, pixel pix)
{
...
}

int main(int argc, char *argv[])
{
  int r, nrows, c, ncols, red, grn, blu;
  colorImage img ;

  /* check the command line parameters */
  if ( argc != 4 )
  {
    printf("fillAndFlood fileName.ppm nrows ncols\n");
    return 0;
  }

  nrows = atoi( argv[2] );
  if ( nrows < 1 )
  {
    printf("number of rows must be positive\n");
    return 0;
  }

  ncols = atoi( argv[3] );
  if ( nrows < 1 )
  {
    printf("number of columns must be positive\n");
    return 0;
  }

  /* create the image structure */
  if ( newColorImage( &img, nrows, ncols ) == NULL )
  {
    printf(">>error<< newColorImage can't allocate memory\n");
    return;
  }

  /* initialize the image to all black */
  pixel blue = {200,200,255};
  fill( img, blue );

  /* put in a few circles */
  pixel p1 = {255, 0, 0};
  drawColorCircle( img, 2*nrows/9, ncols/8, nrows/8,  p1);

  pixel p2 = {0, 200, 150};
  drawColorCircle( img, 1*nrows/2, 1*ncols/2, nrows/4, p2);

  pixel p3 = {200, 200, 75};
  drawColorCircle( img, 5*nrows/7, 3*ncols/4, nrows/5, p3);

  /* write out the image */
  writePPMimage( img, argv[1] );

  /* free memory */
  freeColorImage( &img );
}

 


Puzzle 85 — Draw a Line

[H-15] Write a function that draws a line segment from (row0, col0) to (row1, col1) . The parameters of the function are the endpoints of the line segment and the color of the line. Make the line one pixel thick.

void drawColorLine( colorImage image, int row0, int col0, int row1, int col1, pixel pix);

Here is an image with some sample lines in it.

Many Lines

This is a surprisingly difficult program. Don't be too disappointed if your lines look somewhat ragged. It is hard to draw nice lines. This subject is usually convered in a full chapter of a computer graphics text. Here is a testing framework:

#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "../basicColorImage.c"

/* Draw a line in the image */
void drawColorLine( colorImage image, int row0, int col0,
                    int row1, int col1, pixel pix)
{
. . .
}

void fill( colorImage image, pixel pix)
{
. . .
}

int main(int argc, char *argv[])
{
  int nrows, ncols, x, y;
  colorImage img ;
  double theta;

  /* check the command line parameters */
  if ( argc != 4 )
  {
    printf("drawLines fileName.ppm nrows ncols\n");
    return 0;
  }

  nrows = atoi( argv[2] );
  ncols = atoi( argv[3] );

  /* create the image structure */
  if ( newColorImage( &img, nrows, ncols ) == NULL )
  {
    printf(">>error<< newColorImage can't allocate memory\n");
    return;
  }

  /* initialize the image */
  pixel blue = {200,200,255};
  fill( img, blue );

  /* put in a few lines */
  pixel black = {255, 0, 0};
  for ( theta=0.0; theta<2*M_PI; theta+=M_PI/12.0 )
  {
    y = nrows/2 + (3*nrows/8)*sin(theta);
    x = ncols/2 + (3*ncols/8)*cos(theta);
    drawColorLine( img,  nrows/2, ncols/2, y, x, black );
  }

  /* write out the image */
  writePPMimage( img, argv[1] );

  /* free memory */
  freeColorImage( &img );
}

Hints: (1) divide the function into two parts. One part draws lines that make an angle of 45 degrees or less with the X-axis; the other part draws the other lines. (2) For lines of 45 degrees or less, use a loop to generate each column number from the left end of the line to the right end. For each column, find the row of the pixel that should be set. For the other lines, loop on the row number and find the column number of the pixel to be set. (3) For lines of 45 degrees or less, calculate the slope using the difference of row numbers of the two ends divided by the difference in column numbers. For the other lines, reverse the roles of rows and columns.

 


Puzzle 86 — Spider Web

[M-10] Write a program that uses the line drawing function of the previous puzzle to create an image like that below.

Spider Web

No solution is provided for this puzzle.


Puzzle 87 — Funnel Web

[M-10] Write a program that uses the line drawing function of the previous puzzle to create an image like that below.

Funnel Web

No solution is provided for this puzzle.


Puzzle 88 — Single Pixel

[E-1] Write a program that creates an image that is all black except for a single pixel in the center that is set to the color specified on the command line.

singlePix image.ppm nrows ncols red green blue

This is not a programming challenge, but is a useful image to contemplate when you think about how a single pixel in a digital image (the file on disk) goes through several transformations until it is displayed on a monitor. Note, in particular, how the single pixel does not usually correspond to just one of the physical spots of light that the monitor displays (sometimes called display pixels). Move the image around with the mouse and notice how different physical combinations of display pixels light up depending on where the image pixel is.

Single Pixel Magnified Single Pixel

Look at the pixel with a magnifying glass. If you don't have a magnifying glass, sneeze on your monitor, and little drops of fluid will create magnifying lenses. Move the pixel under one of them. This is especially effective with a CRT monitor. On my monitor, for a single image pixel, there are four fully lit up little spots of light (dots of phosphore on the monitor screen) for each of red, green, and blue, and several more dim spots of each color. It is hard to see this in the above images because the colors are not as saturated as in real life.

 


Puzzle 89 —

[E-5] Write a program that The command line looks like:

C:\PuzzleFolder>

 

No answer is provided for this puzzle.


 


― Return to the main contents page