image.py# Changes:# Modify class name for base image to be AbstractImage This way wedon't have alower case# class name running around. We still don't expect
image.py# Changes:# Modify class name for base image to be AbstractImage This way wedon't have alower case# class name running around. We still don't expect people to createanAbstractImage but# rather create an image through FileImage, ListImage, orEmptyImage.# Add ability to convert an image to a list# Add save function to write an image back to disk.## Version 1.2 November 2007# Changes:# Modify the setPosition function to position the image by the topleft cornerrather than# the center.# Add the exitOnClick method to ImageWin. Use this as the last callin theprogram to# avoid early exits when running from the command line, and nastyhangs whenrunning# from within IDLE## Version 1.3 May 2008# Changes:# Modify all code to be Python 3.0 ready. -- still runs under2.x# Modify all code so that if PIL is not available then image.pywill still# function using Tkimages. N.B. Tk restricts image types to gif orppm## Andrew Mertz, Eastern Illinois University# October 2014# Changes:# Negative indices can be used in Pixel's __getitem__function# Pixel's __getitem__ function now supports looping i.e. for valuein Pixel(0, 1,2):## Giovanni Moretti, Massey University, Palmerston North, NewZealand# April 2015# Changes:# Added _imroot.lift() to ensure that pictures aren't hidden underother Windows# (needed on Windows 7 & Python 3.4. Ubuntu 14.04 was finewithout it).
## version 1.4# Brad Miller# distribute on pypi#try:import tkinterexcept:import Tkinter as tkinterpilAvailable = Truetry:from PIL import Image as PIL_Imagefrom PIL import ImageTkexcept:pilAvailable = False#import exceptions# Borrow some ideas from Zelle# create an invisible global main root for all windowstk = tkinter_imroot = tk.Tk()_imroot.withdraw()# Make sure the displayed window is on top - otherwise drawing canappear to fail.# The _imroot.lift() call was required on Windows 7 - Linux wasfine without it# not sure about Mac, but there are some tips at#http://stackoverflow.com/questions/8691655/how-to-put-a-tkinter-window-on-top-of-the-others_imroot.lift()#_imroot.call('wm', 'attributes', '.', '-topmost', True)#_imroot.after_idle(_imroot.call, 'wm', 'attributes', '.','-topmost', False)def formatPixel(data):if type(data) == tuple:return '{#%02x%02x%02x}'%dataelif isinstance(data,Pixel):return '{#%02x%02x%02x}'%data.getColorTuple()class ImageWin(tk.Canvas):"""ImageWin: Make a frame to display one or more images."""def __init__(self,title="image window",width=640,height=640):"""Create a window with a title, width and height."""master = tk.Toplevel(_imroot)master.protocol("WM_DELETE_WINDOW", self._close)#super(ImageWin, self).__init__(master, width=width,height=height)tk.Canvas.__init__(self, master, width=width, height=height)self.master.title(title)self.pack()master.resizable(0,0)self.foreground = "black"self.items = []
self.mouseX = Noneself.mouseY = Noneself.bind("", self._onClick)self.height = heightself.width = widthself._mouseCallback = Noneself.trans = None_imroot.update()def _close(self):"""Close the window"""self.master.destroy()self.quit()_imroot.update()def getMouse(self):"""Wait for mouse click and return a tuple with x,y position inscreencoordinates afterthe click"""self.mouseX = Noneself.mouseY = Nonewhile self.mouseX == None or self.mouseY == None:self.update()return ((self.mouseX,self.mouseY))def setMouseHandler(self, func):self._mouseCallback = funcdef _onClick(self, e):self.mouseX = e.xself.mouseY = e.yif self._mouseCallback:self._mouseCallback(e.x, e.y)def exitOnClick(self):"""When the Mouse is clicked close the window and exit"""self.getMouse()self._close()def exitonclick(self):self.exitOnClick()class Pixel(object):"""This simple class abstracts the RGB pixel values."""def __init__(self, red, green, blue):super(Pixel, self).__init__()self.__red = redself.__green = greenself.__blue = blueself.max = 255def getRed(self):"""Return the red component of the pixel"""return self.__reddef getGreen(self):"""Return the green component of the pixel"""return self.__green
def getBlue(self):"""Return the blue component of the pixel"""return self.__bluedef getColorTuple(self):"""Return all color information as a tuple"""return (self.__red, self.__green, self.__blue)def setRed(self,red):"""Modify the red component"""if self.max >= red >= 0:self.__red = redelse:raise ValueError("Error: pixel value %d is out of range" %red)def setGreen(self,green):"""Modify the green component"""if self.max >= green >= 0:self.__green = greenelse:raise ValueError("Error: pixel value %d is out of range" %green)def setBlue(self,blue):"""Modify the blue component"""if self.max >= blue >= 0:self.__blue = blueelse:raise ValueError("Error: pixel value %d is out of range" %blue)def __getitem__(self,key):"""Allow new style pixel class to act like a color tuple:0 --> red1 --> green2 --> blue"""if isinstance(key, slice):raise TypeError("Slicing is not supported")if key == 0 or key == -3:return self.__redelif key == 1 or key == -2:return self.__greenelif key == 2 or key == -1:return self.__blueelse:raise IndexError("Error %d Index out of range" % key)def setRange(self,pmax):"""docstring for setRange"""if pmax == 1.0:self.max = 1.0elif pmax == 255:self.max = 255else:raise ValueError("Error range must be 1.0 or 256")def __str__(self):return str(self.getColorTuple())
def __repr__(self):"""docstring for __repr__"""return str(self.getColorTuple())red = property(getRed, setRed, None, "I'm the red property.")green = property(getGreen, setGreen, None, "I'm the greenproperty.")blue = property(getBlue, setBlue, None, "I'm the blueproperty.")class AbstractImage(object):"""Create an image. The image may be created in one of fourways:1. From an image file such as gif, jpg, png, ppm for example: i=image('fname.jpb)2. From a list of lists3. From another image object4. By specifying the height and width to create a blankimage."""imageCache = {} # tk photoimages go here to avoid GC whiledrawnimageId = 1def__init__(self,fname=None,data=[],imobj=None,height=0,width=0):"""An image can be created using any of the following keywordparameters. Whenimage creation iscomplete the image will be an rgb image.fname: A filename containing an image. Can be jpg, gif, andothersdata: a list of lists representing the image. This might besomething youconstruct byreading an asii format ppm file, or an ascii art file and translateintorgb yourself.imobj: Make a copy of another image.height:width: Create a blank image of a particular height and width."""super(AbstractImage, self).__init__()# if PIL is available then use the PIL functions otherwise fallback to Tkif pilAvailable:self.loadImage = self.loadPILImageself.createBlankImage = self.createBlankPILImageself.setPixel = self.setPILPixelself.getPixel = self.getPILPixelself.save = self.savePILelse:self.loadImage = self.loadTkImageself.createBlankImage = self.createBlankTkImageself.setPixel = self.setTkPixelself.getPixel = self.getTkPixelself.save = self.saveTkif fname:self.loadImage(fname)self.imFileName = fnameelif data:height = len(data)width = len(data[0])self.createBlankImage(height,width)for row in range(height):for col in range(width):
self.setPixel(col,row,Pixel(data[row][col]))elif height > 0 and width > 0:self.createBlankImage(height,width)elif imobj:self.im = imobj.copy()if pilAvailable:self.width,self.height = self.im.sizeelse:self.width = self.im.width()self.height = self.im.height()self.centerX = self.width/2+3 # +3 accounts for the ~3 pixel borderinTk windowsself.centerY = self.height/2+3self.id = Nonedef loadPILImage(self,fname):self.im = PIL_Image.open(fname)ni = self.im.convert("RGB")self.im = nidef loadTkImage(self,fname):sufstart = fname.rfind('.')if sufstart < 0:suffix = ""else:suffix = fname[sufstart:]if suffix not in ['.gif', '.ppm']:raise ValueError("Bad Image Type: %s : Without PIL, only .gif or.ppmfiles are allowed" % suffix)self.im = tkinter.PhotoImage(file=fname)def createBlankPILImage(self,height,width):self.im = PIL_Image.new("RGB",(width,height))ni = self.im.convert("RGB")self.im = nidef createBlankTkImage(self,height,width):self.im = tkinter.PhotoImage(height=height,width=width)def copy(self):"""Return a copy of this image"""newI = AbstractImage(imobj=self.im)return newIdef clone(self):"""Return a copy of this image"""newI = AbstractImage(imobj=self.im)return newIdef getHeight(self):"""Return the height of the image"""return self.heightdef getWidth(self):"""Return the width of the iamge"""return self.width
def getTkPixel(self,x,y):"""Get a pixel at the given x,y coordinate. The pixel is returnedas anrgb color tuplefor example foo.getPixel(10,10) --> (10,200,156) """p = self.im.get(x,y)# p is a string in some tkinter versions; tuple in others.try:p = [int(j) for j in p.split()]except AttributeError:passreturn Pixel(p[0],p[1],p[2])def setTkPixel(self,x,y,pixel):"""Set the color of a pixel at position x,y. The color must bespecifiedas an rgb tuple (r,g,b) wherethe rgb values are between 0 and 255."""if x < self.getWidth() and y < self.getHeight():self.im.put(formatPixel(pixel.getColorTuple()),(x,y))else:raise ValueError("Pixel index out of range.")def getPILPixel(self,x,y):"""docstring for getPILPIxel"""p = self.im.getpixel((x,y))return Pixel(p[0],p[1],p[2])def setPILPixel(self,x,y,pixel):"""docstring for setPILPixel"""if x < self.getWidth() and y < self.getHeight():self.im.putpixel((x,y),pixel.getColorTuple())else:raise ValueError("Pixel index out of range")def setPosition(self,x,y):"""Set the position in the window where the top left corner of thewindowshould be."""self.top = yself.left = xself.centerX = x + (self.width/2)+3self.centerY = y + (self.height/2)+3def getImage(self):if pilAvailable:return ImageTk.PhotoImage(self.im)else:return self.imdef draw(self,win):"""Draw this image in the ImageWin window."""ig = self.getImage()self.imageCache[self.imageId] = ig # save a reference else Tk losesit...AbstractImage.imageId = AbstractImage.imageId + 1self.canvas=winself.id =self.canvas.create_image(self.centerX,self.centerY,image=ig)_imroot.update()def saveTk(self,fname=None,ftype='gif'):if fname == None:
fname = self.imFileNamesufstart = fname.rfind('.')if sufstart < 0:suffix = ""else:suffix = fname[sufstart:]if suffix == "":suffix = "."+ftypefname = fname+suffixif suffix not in ['.gif', '.ppm']:raise ValueError("Without PIL, only .gif or .ppm files areallowed")try:self.im.write(fname,format=ftype)except IOError as e:print(e)print("Error saving, Could Not open ", fname, " to write.")except tkinter.TclError as tke:print(tke)print("gif files can only handle 256 distinct colors")def savePIL(self,fname=None,ftype='jpg'):if fname == None:fname = self.imFileNamesufstart = fname.rfind('.')if sufstart < 0:suffix = ""else:suffix = fname[sufstart:]if suffix == "":suffix = "."+ftypefname = fname+suffixtry:self.im.save(fname)except:print("Error saving, Could Not open ", fname, " to write.")def toList(self):"""Convert the image to a List of Lists representation"""res = []for i in range(self.height):res.append([])for j in range(self.width):res[i].append(self.getPixel(j,i))return resclass FileImage(AbstractImage):def __init__(self,thefile):super(FileImage, self).__init__(fname = thefile)class Image(FileImage):passclass EmptyImage(AbstractImage):def __init__(self,cols,rows):super(EmptyImage, self).__init__(height = rows, width = cols)
class ListImage(AbstractImage):def __init__(self,thelist):super(ListImage, self).__init__(data=thelist)# Example program Read in an image and calulate the negative.if __name__ == '__main__':win = ImageWin("My Window",480,640)oImage = FileImage('lcastle.gif')print(oImage.getWidth(), oImage.getHeight())oImage.draw(win)myImage = oImage.copy()for row in range(myImage.getHeight()):for col in range(myImage.getWidth()):v = myImage.getPixel(col,row)v.red = 255 - v.redv.green = 255 - v.greenv.blue = 255 - v.blue# x = map(lambda x: 255-x, v)myImage.setPixel(col,row,v)myImage.setPosition(myImage.getWidth()+1,0)myImage.draw(win)print(win.getMouse())myImage.save('lcastle-inverted.gif')print(myImage.toList())win.exitOnClick()
Write a program that uses cImage library and draws the below image. Use color green to draw the vertical and horizontal lines. Use red to draw the right-lower diagonal line. Sample output My Image Xx
Step by Step Solution
3.39 Rating (161 Votes )
There are 3 Steps involved in it
Step: 1
import plotlyexpress as px df pxdatairis ...See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started