Due: , 11:59 pm
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 project4. Then download the following files to it.
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 project4 folder.
After the comment line, write the command to tell Python to import the graphics package, the display package, and the sys package:
import graphics import display import sys
Download one of the following images to use in the lab exercises. You should right-click on the image and choose "Save Link As...". Choosing "Save Image As..." will not work because the image will be saved as a PNG rather than a PPM, and the Zelle graphics library will only read images in the PPM format.
If you would like to use any additional photos, then you may want to make the images smaller for testing. You can use the convert program to change the size of any image. For example:
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 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. For example:
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.
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, while 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.
Any time we need to store, retain, or assign information, we need to use an assignment statement. In this case, we want to store the Image object created by the graphics.Image() function call. Therefore, you need a variable on the left side of an assignment and the graphics.Image() function call on the right.
Below the main function, put a conditional call to it, using the method we learned last week. Pass the main function the list sys.argv.
if __name__ == "__main__": main(sys.argv)
Once complete, try out your show() function. In 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
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 Zelle graphics library (graphics.py) contains two functions that make it easy to get and set pixels if you have an Image object. The three lines below demonstrate how you would read in a Image from a file (which we did above) and then swap the red and blue channels of pixel 42 (x), 35 (y).
img = graphics.Image(graphics.Point(0,0), 'myImage.ppm' ) (r, g, b) = img.getPixel( 42, 35 ) img.setPixel( 42, 35, graphics.color_rgb(b, g, r ) )
Create a new file called filter.py. Do the usual stuff of putting your name and the date at the top. Then import graphics and sys. Save it in your project4 directory.
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.
def swapRedBlue( src ): # loop over each row row_idx # loop over each column col_idx # get the r, g, b values of the pixel indexed by (col_idx, row_idx) # set the pixel indexed by (col_idx, row_idx) to the value (b, g, r) # return
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. You can use show.py as an example for your test function. As in that example, first test if there are enough arguments and print out a usage statement and exit if there are not.
If there are enough arguments, then open the image and store the result in a variable. Pass the Image to the swapRedBlue function, then save the result to a file. If your Image variable were img, then you could save it by using
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, as we did last week.
if __name__ == "__main__": test( 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. Now, perhaps, you see why command line parameters are useful.
When you are done with the lab exercises, you may start on the rest of the project.
© 2018 Caitrin Eaton.