#---------------------------------------------------------------------- # Fleshed-out command processor for image processing. # # (C) Copyright March 7, 2018 -- Dr. William T. Verts # # New things: # # (1) The basic command processor now involves a canvas for doing # graphics. It starts with a default canvas, and always shows the # current result in the canvas before getting each new command. # The canvas will be passed around to various functions for updates. # # (2) Command OPEN is implemented in-place in the command processor # because it requires only a couple of statements. Other commands # take much more code, so for those commands the code is encapsulated # into functions. # # (3) In the first approach, each image-processing function is # complete and self contained (Brighten, Darken, Monochrome, and # GrayScale). This works just fine, but much of the code is repeated # between the functions: the double loop, the getPixel line, and # the repaint. All that differs between the functions is what # happens to each pixel. # # (4) In the second approach, the common code has been factored out # into a single function called Process. The Process function does # all the pixel scanning, but it must be told which of a number of # very simple pixel functions to apply to the pixels. The new thing # here is that functions may be parameters to other functions. #---------------------------------------------------------------------- import string #---------------------------------------------------------------------- # Individual functions to do some image processing task. Notice how # much of the code is duplicated between the functions. #---------------------------------------------------------------------- def Brighten (Canvas): for Y in range(getHeight(Canvas)): for X in range(getWidth(Canvas)): PX = getPixel(Canvas,X,Y) setRed (PX, getRed (PX)+20) setGreen(PX, getGreen(PX)+20) setBlue (PX, getBlue (PX)+20) repaint(Canvas) return def Darken (Canvas): for Y in range(getHeight(Canvas)): for X in range(getWidth(Canvas)): PX = getPixel(Canvas,X,Y) setRed (PX, getRed (PX)-20) setGreen(PX, getGreen(PX)-20) setBlue (PX, getBlue (PX)-20) repaint(Canvas) return def Monochrome(Canvas): for Y in range(getHeight(Canvas)): for X in range(getWidth(Canvas)): PX = getPixel(Canvas,X,Y) Average = (getRed(PX) + getGreen(PX) + getBlue(PX)) / 3 if Average > 128: setColor(PX,white) else: setColor(PX,black) repaint(Canvas) return def GrayScale(Canvas): for Y in range(getHeight(Canvas)): for X in range(getWidth(Canvas)): PX = getPixel(Canvas,X,Y) Average = (getRed(PX) + getGreen(PX) + getBlue(PX)) / 3 setRed (PX,Average) setGreen(PX,Average) setBlue (PX,Average) repaint(Canvas) return #---------------------------------------------------------------------- # Here most of the functions do something to a pixel, but that is it. # The double-loop, getPixel, and repaint have been factored out into # the Process function, which in order to work must be passed as a # parameter (FN) the actual pixel function to be applied. #---------------------------------------------------------------------- def Brighten_Pixel(PX): setRed (PX, getRed (PX)+20) setGreen(PX, getGreen(PX)+20) setBlue (PX, getBlue (PX)+20) return def Darken_Pixel(PX): setRed (PX, getRed (PX)-20) setGreen(PX, getGreen(PX)-20) setBlue (PX, getBlue (PX)-20) return def Monochrome_Pixel(PX): Average = (getRed(PX) + getGreen(PX) + getBlue(PX)) / 3 if Average > 128: setColor(PX,white) else: setColor(PX,black) return def Process (Canvas, FN): for Y in range(getHeight(Canvas)): for X in range(getWidth(Canvas)): FN(getPixel(Canvas,X,Y)) repaint(Canvas) return #---------------------------------------------------------------------- # The updated command processor. Notice that GrayScale still uses # the explicit function, and hasn't yet been updated to the new # style using Process. All the other image commands call Process, # but must tell Process which pixel function to use as parameter FN. #---------------------------------------------------------------------- def Main(): Message = """Enter a Command from the list: QUIT OPEN SAVE BRIGHTEN DARKEN MONO GRAY FOCUS EMBOSS CONTRAST Enter a command --- """ Canvas = makeEmptyPicture(100,100) MoreToDo = True while (MoreToDo): repaint(Canvas) S = string.upper(requestString(Message)) print S if (S == "QUIT" ): MoreToDo = False elif (S == "OPEN" ): Filename = pickAFile() Canvas = makePicture(Filename) elif (S == "SAVE" ): pass elif (S == "BRIGHTEN"): Process(Canvas, Brighten_Pixel) elif (S == "DARKEN" ): Process(Canvas, Darken_Pixel) elif (S == "MONO" ): Process(Canvas, Monochrome_Pixel) elif (S == "GRAY" ): GrayScale(Canvas) else: showError("ERROR, " + S + " is not a legal command") return