CpSc 101, Fall 2015 Lab7: Image File Creation Goals Construct a C language program that will produce images of the flags of Poland, Netherland, and Italy. Image files Images (e.g. digital photos) consist of a rectangular array of discrete picture elements called pixels. An image consisting of 200 rows of 300 columns (or pixels per row) contains 300 x 200 = 60,000 individual pixels. The height of the image in pixels is the number of pixel rows, and the width is the number of columns, or pixels in each row. A color image requires 3 bytes per pixel or 180,000 total bytes! The Portable PixMap (.ppm) format is a particularly simple way used to encode a rectangular image (picture) as uncompressed data file. Other well known formats include JPEG (.jpg), TIFF (.tif), GIF (.gif), bitmap (.bmp), and PNG (.png) The.ppm file can viewed with a number of tools including display and gimp. MS Windows systems have no built-in.ppm viewer. Several freeware viewers are available on the web though. See (www.gimp.org/downloads) for downloading gimp onto your own laptop. You ll see a link for use on a Mac at the top of that page. For Windows, click on Show Other Downloads, which is about 1/3 of the way down (right below Fink ). Another image viewer/editor is irfanview, though there is no version for Macs. See (www.irfanview.com) for more information.
PPM file format ppm files: ppm is a very simple image file format. A ppm image consists of two components: 1. The header: the header contains 1) a label to identify the file format as a color ppm file ("P6"), 2) the width of the image in pixels, 3) the height of the image in pixels and 4) the maximum pixel value (always 255). 5) the header ends with a single \n newline character 2. Binary image data: the data consists of unsigned char (eight-bits == one-byte) binary values defining the color of each pixel. Example ppm header: The header of a color image of 800 pixels wide and 600 pixels high has the following format: P6 800 600 255 Then the very next line after the 255 is where the pixel data begins. You can open the.ppm file using vim or some other editor, and you ll be able to see and makes sense of the header; but since the pixel data is binary, the rest of the file after the header will look like a bunch of weird, unreadable characters. Pixel data format: each pixel consists of 3 one-byte values of type unsigned char the first three bytes of image data in the.ppm file define the color of the pixel in the upper left corner of the image the last three bytes in the file define the color of the pixel in the lower right pixel values defining each horizontal row of the image are adjacent NO spaces, tabs, newlines may be embedded in the file.
red/green/blue image encoding this format is called RGB. The three bytes of each pixel represent the color intensities of the: red component green component blue component (255, 0, 0) is bright red (0, 255, 0) is bright green (0, 0, 255) is bright blue Colors are additive (255, 255, 0) = red + green = bright yellow (255, 0, 255) = red + blue = magenta (purple) (0, 255, 255) = blue + green = cyan (turquoise) (255, 255, 255) = red + green + blue = white when red == green == blue (lower than 255), a gray color is produced; for example, (25, 25, 25) would be a light shade of gray, and (200, 200, 200) would be a darker shade of gray Writing a pixel value The %c format code tells fprintf() NOT to convert the value being printed to ASCII format. Since pixel values are binary, the %c code must be used. The following statement can be used to write a red pixel: fprintf(stdout, "%c%c%c", 255, 0, 0); NO spaces or newlines are permitted in the format string!!
Assignment Write a program called lab7.c that is capable of creating an image of the flags of Poland, Netherland, and Italy. Two integer values should be read from the standard input: country_code: 0 - Poland 1 - Netherland 2 - Italy width: The width of the flag in pixels. You should use the proper colors as defined in Wikipedia based upon a google search for "Flag of Poland", etc. Google rgb colors to find the r, g, & b values for each color that you will need for the above flags. You should use the proper ratio of height to width as specified by proportion in Wikipedia to compute the height of the image you produce. Poland: https://en.wikipedia.org/wiki/flag_of_poland (RGB: white (255, 255, 255), red (255, 0, 0)) Netherland: https://en.wikipedia.org/wiki/flag_of_the_netherlands Italy: https://en.wikipedia.org/wiki/flag_of_italy Use the make_pixel() function provided below: void make_pixel ( int r, // red intensity int g, // green intensity int b ) // blue intensity { fprintf(stdout, "%c%c%c", r, g, b); } Use the make_ppm_header() function provided below: void make_ppm_header (int width, int height) { fprintf(stdout, "P6\n"); fprintf(stdout, "%d %d %d\n", width, height, 255); }
Use the following main() function. #include <stdio.h> int main() { int width; int country_code; // prompt user to enter width and country_code of chosen flag /* Read image dimensions and pixel color */ fscanf(stdin, "%d %d", &country_code, &width); fprintf(stderr, "Making country %d with width %d \n", country_code, width); /* Write the image data */ make_ppm_image(country_code, width); } return(0); You will need to write the function make_ppm_image(country_code, width) to create the chosen flag. You can do this one of two ways: 1. use an if-else, or switch, statement based on the country code and put the code to create the flags within each part of the if-else (or switch) 2. use an if-else, or switch, statement to call one of 3 other functions depending on which country code was sent in (this is preferable because this keeps the make_ppm_image() function smaller by breaking each task up and putting the code for each flag into other separate, smaller functions) Whichever way you choose to do it, work on the Poland one first (because it is the easier one of the three); make sure it works before continuing on to Netherland s flag; make sure that one works, then do the last one. You should always break up your programs into small parts, doing each one incrementally, compiling in between each step before continuing on to the next step.
Producing and viewing the image 1. Write the C program to produce the image. In your program, you will have statements to write the header information. You are provided with the function HINTS: called make_ppm_header() which will write the header information to stdout. 2. Then your program will include statements to write the r, g, b pixel data to the file. You are provided with the function called make_pixel() to which you will send the r, g, b values. This function will be called from another function that you will be writing. 3. Don t forget to put all your prototypes at the top of your lab7.c file underneath the #include statement(s). 4. You will compile your program as you normally compile C programs: gcc -Wall -g lab7.c 5. When you run the program, you will redirect the output to a specified ppm filename. For example, if you are going to test the Poland flag, you would type the following:./a.out > poland.ppm 6. You will be prompted to enter the width and the country code for the flag, and then the.ppm file will be created. 7. To view the image, you can use one of the methods mentioned above on page 1. You will probably end up using nested for loops. You may utilize whatever lecture notes were provided to you. There are different ways of producing the images. For example: some lecture notes show examples of the nested for loops to control the rows and columns (the outer for loop is for each row; and the inner for loop(s) produce the pixels along the row). Other notes may show examples of using the modulus operator with an if statement to determine the row/column that you are currently looking at. Either approach is fine. Your program should compile WITHOUT warnings with gcc -Wall -g lab7.c Turn In Work Show your TA that you completed the assignment. Then turn in your lab7.c program using the handin page at http://handin.cs.clemson.edu