Lab Exercise 6: Images
The main purpose of this lab is to give you the tools you need to complete an image-manipulation project. You will be using John Zelle's graphics package. Here is the reference guide.
In your personal file space, make a folder called project6. Download the graphicsPlus.py file for the Zelle graphics package.
Open a text editor (e.g TextWrangler). Create a new file called show.py. Put a comment at the top of the file with your name and the date. Save it in your project6 folder.
After the comment lines, write the command to tell Python to import the graphics package and the sys package:
import graphicsPlus as gr import sys
Download one of the following images to use in the lab exercises. You should right-click on the Image and do "Save Link As..."
If you want to use your own images, check out the more detail section.
+ (more detail)
If you would like to use any additional photos, then you may want to make the images smaller for testing. On the lab computers, You can use the convert program to change the size of any image. (Note: if you want to use convert on your own computer, you will need to install ImageMagick. Alternatively, you can use a web-based image-converter.)
convert myImage.jpg -scale 25% mySmallImage.jpg
You can also change an image of one format to a different format. The Zelle graphics library can open only PPM format images, not JPGs. You can change a JPG to a PPM using one of the following examples.
convert myImage.jpg myImage.ppm
PNG and JPG images are the formats for you will need to use for your reports or for web pages. Note that you can change the format and change the scale at the same time.
convert myImage.jpg -scale 25% myImage.ppm
The convert program is a very powerful application for manipulating images. If you want to find out more about it, check out the ImageMagick web site.
- Write a program to read and display an image
The first thing we're going to do is create a simple program that will read image data from a file and display it in a window. We'll use the command line to specify the filename of the image to view.
Create a main function in your show.py file. Give it one argument, argv, which will be the list of strings from the command line. One of these strings should be the filename of the image to open and view. The main function should do the following.
- Check if the user provided enough command-line arguments
Test if there are at least two strings in the main function parameter: the name of the python program and the filename of the image to open. If there are not at least two strings, print a usage message and exit using the exit() function. Use the len() function to test how many strings there are in the argv list.
- Use the graphics.Image function to read image data from a file
Load image data from the file specified in the second string of the main function parameter into an Image. Assign to a variable (e.g. src) the result of calling the function graphics.Image() with a Zelle Point object (graphics.Point(0, 0)) as the first argument and the filename as the second argument. The filename will be the second element in the list argv that is the parameter of your main function. Assign the return value of the graphics.Image function to a variable.
Use an assignment statement any time you need to store, retain, or assign information. In this case, we want to store the Image object created by the graphics.Image() function call. Therefore, put a variable name on the left side of an assignment and the graphics.Image() function call on the right.
- Use the getWidth() and getHeight() methods of the Image object to get its size.
Assign to width the result of calling the image's getWidth method. Assign to height, the result of calling the image's getHeight method.
- Create a GraphWin window to display the image
Using the width and height variables, create a GraphWin object with a title of your choice that is the same size as the Image.
- Move the image to the center of the window
Using the move method of the image, we want to position the image in the center of the window. The Image has a method getAnchor() that returns a graphics Point object that holds its current location. The center of the window is (width/2, height/2). Move the Image by the difference between the two. For example, (width/2) - getAnchor().getX() is how much to move the image in the x direction.
- Draw the Image into the window
Use the Image's draw method (just like any other graphics object) to draw the image into the window at its current anchor point.
- Wait for user input
Finally, call the getMouse method of the window. That means you type the name of the variable holding the window reference, then .getMouse() to call the method. This will wait for a mouse click in the window and then go on to the next instruction. If there is no next instruction, the program will terminate.
Below the main function, put a conditional call to it. Pass the main function the list sys.argv.
if __name__ == "__main__": main(sys.argv)
Once complete, try out your show function. On the terminal, make sure you are in the correct working directory and then run your program with an image filename as a command line argument.
python3 show.py geraniums.ppm
- Check if the user provided enough command-line arguments
- Manipulate the pixels of an image
The second thing we're going to do in lab is figure out how to manipulate pixels in an image. Each pixel in a color image has three values (r, g, b). Each pixel is addressed by its row and column. There are rows x columns pixels in an image. The Image object has two methods that let you access and modify pixels.
- getPixel( col, row ): returns the (r, g, b) tuple located at (col row)
- setPixel( col, row, color): assigns the given color to the image at (col, row)
The following shows an example of how you might use these functions, where src is the variable holding your Image object.
(r, g, b) = src.getPixel( 42, 35 ) src.setPixel( 42, 35, graphics.color_rgb(b, g, r ) )
If you want to practice accessing or modifying pixels, you can edit your show.py function in between creating the image and drawing the image into the window.
- Start a library of photo filters
Create a new file called filter.py. Do the usual stuff of putting your name and a date at the top. Then import graphics and sys. Save it in your Project6 directory.
In filter.py, create a function named something like swapRedBlue that takes in one argument, which will be a Image object. The algorithm is written below as comments, properly indented. Read through them and make sure you understand the process. Then fill in the python code. After the Python code has been written, please remove these comments. They do not make the code any more readable, as they are just the English version of the code.
The number of rows in the image is provided by src.getHeight() if src is the Image object. The number of columns in the image is provided by src.getWidth()
def swapRedBlue( src ): # for each row row_idx in the image # for each column col_idx in the image # assign to (r, g, b) the pixel values at (col_idx, row_idx) # set the pixel indexed by (col_idx, row_idx) to the value (b, g, r)
- Test your photo filter
Create a new test function in filter.py (this is a different function than swapRedBlue) that takes in an argument which is the list of strings from the command line.
A simple option is to copy the main function from show.py and then call swapRedBlue(src) after reading the image and before displaying it.
You can also save an image to a new file. If your Image variable is src, you can save it to the file myfilename.ppm by using the following.
You can pass whatever filename name you want to the save function. I'd recommend not having spaces in the name.
At the end of your filter.py file, put a call to your test function behind a conditional that tests the value of the __name__ variable.
if __name__ == "__main__": main( sys.argv )
Note that this is the only place in your filter.py file where you should use the sys.argv variable. if you are using it in any of your functions, then you are not making proper use of the function parameters.
When you are done, run your filter.py program, giving it an image filename as the argument. Then look at the result with your show program.
When you are done with the lab exercises, you may begin the project.