I'm trying to do an exercise in John Zelle's "Python Programming: An Introduction to Computer Science". I downloaded a special graphics package for his book (graphics.py, which is on the linked website). The question reads as follows:
Write a program that converts a color image to grayscale. The user supplies the name of a file containing a GIF or PPM image, and the program loads the image and displays the file. At the click of the mouse, the program converts the image to grayscale. The user is then prompted for a filename to store the grayscale image in.
You will probably want to go back and review the Image object from the graphics library (Section 4.8.4). The basic idea for converting the image is to go through it pixel by pixel and convert each one from color to an appropriate shade of gray. A gray pixel created by setting its red, green, and blue components to have the same brightness. So, color_rgb(0, 0, 0)
is black, color_rgb(255, 255, 255)
is white, and color_rgb(127, 127, 127)
is a gray "halfway" in between. You should use a weighted average of the original rgb values to determine the brightness of the gray. Here is the pseudocode for the grayscale algorithm [for some reason the four-space indent is not working on preview]:
for each row in the image:
for each column in the image:
r, g, b = get pixel information for current row and column
brightness = int(round(0.299r + 0.587g + 0.114b))
update the image # to see progress row by row
Note: the pixel operations in the Image
class are rather slow, so you will want to use relatively small images (not 12 megapixels) to test your program.
I've been working on this for hours. This is the latest version of my code:
# grayscale.py
from graphics import *
def main():
infileName = input("File name: ")
outfileName = input("Save to: ")
image = Image(Point(100,100), infileName)
width = image.getWidth()
height = image.getHeight()
win = GraphWin("rgb")
image.draw(win)
row = 0
column = 0
win.getMouse()
for row in range(200):
for column in range(200):
r, g, b = image.getPixel(row, column)
brightness = int(round(0.299 * r + 0.587 * g + 0.114 * b))
image.setPixel(row, column, color_rgb(brightness, brightness, brightness))
win.update()
win.getMouse()
win.close()
main()
I finally got it so Python's not giving me any error messages. But all the program does is load the image, take a couple of mouse clicks, and then close. I've been entering the input file as U:\My Pictures\yay.gif, and the output file as U:\My Pictures\yay2.gif. But I just searched my computer and U:\My Pictures\yay2.gif doesn't exist. What am I doing wrong? This is NOT for a class by the way--there's no instructor for me to ask.
Maybe I should follow up in the post instead. I added the save function, but I got an image with a 200x200 grayscale box and the rest of it in color. So, here are some lines I changed:
win = GraphWin("rgb", width, height)
for row in range(height):
for column in range(width):
And I get the following error message:
Traceback (most recent call last):
File "C:\Python31\grayscale.py", line 31, in
main()
File "C:\Python31\grayscale.py", line 22, in main
r, g, b = image.getPixel(row, column)
File "C:\Python31\lib\graphics.py", line 810, in getPixel
value = self.img.get(x,y)
File "C:\Python31\lib\tkinter_init_.py", line 3301, in get
return self.tk.call(self.name, 'get', x, y)
_tkinter.TclError: pyimage1 get: coordinates out of range
I understand that I probably need to change the anchor point of the image to the center. But I can only determine that by the image's width and height, and I have to have uploaded the image first to get those values. Is there a workaround?