# # Media Wrappers for "Introduction to Media Computation" # Started: Mark Guzdial, 2 July 2002 # Revisions: # #################################################################### # 7 November 2005: (Alyce Brady, Kalamazoo College) # Fixed copyInto and crop to subtract 1 from the x and y parameters # before invoking the Java-level functions. # # 17 October 2005: (Alyce Brady, Kalamazoo College) # Changed the name of getSample function to getSampleValue to make # for more readable user code. (Arguably should have added # a new function and left getSample there because it appears in # the textbook.) # Fixed getPixels method in Picture class to include 1st row & 1st # column of the picture. # Fixed createImage in Picture class to correct the dimensions. # Modified createImage method in Picture class to take an extra color # parameter to support the modified makeEmptyPicture function. # Modified setColor method in Pixel class to call change the # underlying pixel color once rather than 3 times through separate # calls to setRed, setGreen, and setBlue. (Considerable speedup # in calls to global setColor function!) # Modified Color class to store single java.awt.Color object as its # state, eliminating need to synchronize multiple representations # of same value. This also sped up calls to the global setColor # function, at least when copying colors to other pixels. # Fixed setRGB to use indices 0 .. 2, to be consistent with getRGB, # but then later commented out whole method (see below). # Modified global pickAColor function to use the named constant black # rather than Color(0,0,0). # Modified the construction of the color constants to use the global # makeColor function. # Modified global makeEmptyPicture function to allow users to specify # a background color (previous function always provided a black # background). # Added global getAllPixels function as clearer name for getPixels. # Added global crop, duplicate, and copyInto functions as 3 generally # useful functions that, if provided upfront, are significantly # faster (approx. 1/10th the time) than if implemented by students # using getPixel/getColor/setColor. Added crop and copyInto methods # to Picture class to support global crop & copyInto functions. # Added range checking to global setRed, setGreen, and setBlue functions. # Commented out the modifier methods in Color that were not being # used elsewhere in this file (setRed/Green/Blue, setRGB, setJcolor) # to reduce the chance of changing the value of color "constants." # NOT FIXED: the Color class is not completely immutable -- the # makeLighter and makeDarker methods are still there -- making # it possible to lighten and darken color constants. # # 28 October 2005: (Alyce Brady, Kalamazoo College) # Changed all __class__ comparisons to use isinstance instead so that # they will work with subclasses as well (e.g., subclasses of # Picture are still pictures) #################################################################### # # 18 June 2003: (ellie) # Added (blocking)play(AtRate)InRange methods to Sound class # and global sound functions # Changed getSampleValue, setSampleValue to give the appearance # of 1-based indexing # Added getLeftSampleValue and getRightSampleValue to Sound class # 14 May 2003: Fixed discrepancy between getMediaPath and setMediaFolder (AdamW) # 8 Nov: Fixed getSamplingRate (MarkG) # 1 Nov: Fixed printing pixel # 31 Oct: Fixed pickAColor (MarkG) # 30 Oct: Added raises, fixed error messages. Added repaint (MarkG) # 10 Oct: Coerced value to integer in Sound.setSampleValue (MarkR) # 2 Oct: Corrected calls in setSampleValueAt (MarkG): # 30 Aug: Made commands more consistent and add type-checking (MarkG) # 2 Aug: Changed to getSampleValueAt and setSampleValueAt (MarkG) # # TODO: ## Fix HSV/RGB conversions -- getting a divide by zero error when max=min # Get the Java Pieces import JavaSound import JavaPicture import JavaPixel import JavaMusic import java.awt.Color as jcolor import java.awt.Font as jfont import java.awt as awt import javax.swing as swing import java.util import sys import os import math import traceback # Support a media shortcut mediaFolder = os.getcwd() + os.sep # Store last pickAFile() opening _lastFilePath = "" #Set a path to the media for those who want to have a shortcut (5/14/03 AW) def setMediaPath(): global mediaFolder file = pickAFolder(); mediaFolder = file+os.sep print "New media folder: "+mediaFolder def getMediaPath(filename): global mediaFolder file = mediaFolder+filename if not os.path.isfile(file): print "Note: There is no file at "+file return file #And for those who think of things as folders (5/14/03 AW) def setMediaFolder(): global mediaFolder file = pickAFolder(); mediaFolder = file+os.sep print "New media folder: "+mediaFolder def getMediaFolder(filename): global mediaFolder file = mediaFolder+filename if not os.path.isfile(file) or not os.path.isdir(file): print "Note: There is no file at "+file return file def getShortPath(filename): dirs = filename.split(os.sep) if len(dirs) < 1: return "." elif len(dirs) == 1: return dirs[0] else: return (dirs[len(dirs) - 2] + os.sep + dirs[len(dirs) - 1]) # # Sound # class Sound: def __init__(self,filename=None): global mediaFolder self.s = JavaSound() if (filename == None): self.s = JavaSound() else: try: if not os.path.isabs(filename): filename = mediaFolder + filename self.filename = filename self.s.loadFromFile(filename) except: print "Filename "+filename+" could not be read." print "Are you sure it's a valid sound file?" def __str__(self): return "Sound of length "+str(self.getLength()) def __rep__(self): return "Sound of length "+str(self.getLength()) def makeEmptyLength(self,sec): self.s = JavaSound(sec) def play(self): try: self.s.play() except: print "Trouble accessing the sound device." def playAtRate(self,rate): try: self.s.playAtRateDur(rate,self.getLength()) except: exc_type, exc_value, exc_tb = sys.exc_info() print exc_type print exc_value print traceback.extract_tb(exc_tb) print "Trouble accessing the sound device." def playAtRateDur(self,rate,dur): try: self.s.playAtRateDur(rate,dur) except: exc_type, exc_value, exc_tb = sys.exc_info() print exc_type print exc_value print traceback.extract_tb(exc_tb) print "Trouble accessing the sound device." #added 18June03 - new functionality in JavaSound.java def playInRange(self,start,stop): try: self.s.playAtRateInRange(1,start-1,stop-1) #JavaSound is 0-indexed except: exc_type, ex_value, exc_tb = sys.exc_info() print exc_type print exc_value print traceback.extract_tb(exc_tb) print "Trouble accessing the sound device." #added 18June03 - new functionality in JavaSound.java def playAtRateInRange(self,rate,start,stop): try: self.s.playAtRateInRange(rate,start-1,stop-1) #JavaSound is 0-indexed except: exc_type, ex_value, exc_tb = sys.exc_info() print exc_type print exc_value print traceback.extract_tb(exc_tb) print "Trouble accessing the sound device." def blockingPlay(self): try: self.s.blockingPlay() except: print "Trouble accessing the sound device." def blockingPlayAtRate(self,rate): try: self.s.blockingPlayAtRateDur(rate,self.getLength()) except: exc_type, exc_value, exc_tb = sys.exc_info() print exc_type print exc_value print traceback.extract_tb(exc_tb) print "Trouble accessing the sound device." def blockingPlayAtRateDur(self,rate,dur): try: self.s.blockingPlayAtRateDur(rate,dur) except: exc_type, exc_value, exc_tb = sys.exc_info() print exc_type print exc_value print traceback.extract_tb(exc_tb) print "Trouble accessing the sound device." #added 18June03 - new functionality in JavaSound.java def blockingPlayInRange(self,start,stop): try: self.s.blockingPlayAtRateInRange(1,start-1,stop-1) #JavaSound is 0-indexed except: exc_type, ex_value, exc_tb = sys.exc_info() print exc_type print exc_value print traceback.extract_tb(exc_tb) print "Trouble accessing the sound device." #added 18June03 - new functionality in JavaSound.java def blockingPlayAtRateInRange(self,rate,start,stop): try: self.s.blockingPlayAtRateInRange(rate,start-1,stop-1) #JavaSound is 0-indexed except: exc_type, ex_value, exc_tb = sys.exc_info() print exc_type print exc_value print traceback.extract_tb(exc_tb) print "Trouble accessing the sound device." def getSamples(self): return Samples(self) def getLength(self): return self.s.getLengthInFrames() def getSampleValue(self,index): return self.s.getSample(index-1) #JavaSound is 0-indexed #added 18June03 - new functionality in JavaSound.java def getLeftSampleValue(self,index): return self.s.getLeftSample(index-1) #JavaSound is 0-indexed #added 18June03 - new functionality in JavaSound.java def getRightSampleValue(self,index): return self.s.getRightSample(index-1) #JavaSound is 0-indexed def setSampleValue(self,index,value): return self.s.setSample(index-1,int(value)) #JavaSound is 0-indexed #changed 20June03 - JavaSound uses an AudioFileFormat now def getSamplingRate(self): return self.s.getAudioFileFormat().getFormat().getSampleRate() def getSampleObjectAt(self,index): return Sample(self,index) def writeTo(self,filename): global mediaFolder if not os.path.isabs(filename): filename = mediaFolder + filename self.s.writeToFile(filename) class Samples: def __init__(self,aSound): self.myList = [] self.sound = aSound for s in range(1,aSound.getLength()): self.myList.append(Sample(aSound,s)) def __str__(self): return "Samples, length "+str(self.sound.getLength()) def __rep__(self): return "Samples, length "+str(self.sound.getLength()) def __getitem__(self,item): return self.myList[item] def __setitem__(self,item,value): self.sound.setSampleValue(item,value) def getSound(self): return self.sound class Sample: def __init__(self,aSound,index): self.sound=aSound self.index=index def __str__(self): return "Sample at "+str(self.index)+" value at "+str(self.getValue()) def __rep__(self): return "Sample at "+str(self.index)+" value at "+str(self.getValue()) def setValue(self,value): self.sound.setSampleValue(self.index,int(round(value))) def getValue(self): return self.sound.getSampleValue(self.index) def getSound(self): return self.sound ## ## Global sound functions ## def makeSound(filename): global mediaFolder if not os.path.isabs(filename): filename = mediaFolder + filename if not os.path.isfile(filename): print "There is no file at "+filename raise ValueError return Sound(filename) def makeEmptySound(size): snd = Sound() snd.makeEmptyLength(size) return snd def getSamples(sound): if not isinstance(sound, Sound): print "getSamples(sound): Input is not a sound." raise ValueError return Samples(sound) def play(sound): if not isinstance(sound, Sound): print "play(sound): Input is not a sound." raise ValueError sound.play() def blockingPlay(sound): if not isinstance(sound, Sound): print "blockingPlay(sound): Input is not a sound." raise ValueError sound.blockingPlay() def playAtRate(sound,rate): if not isinstance(sound, Sound): print "playAtRate(sound,rate): Input is not a sound." raise ValueError sound.playAtRate(rate) def playAtRateDur(sound,rate,dur): if not isinstance(sound, Sound): print "playAtRateDur(sound,rate,dur): Input is not a sound." raise ValueError sound.playAtRateDur(rate,dur) #20June03 new functionality in JavaSound (ellie) def playInRange(sound,start,stop): if not isinstance(sound, Sound): print "playInRange(sound,start,stop): Input is not a sound." raise ValueError sound.playInRange(start,stop) #20June03 new functionality in JavaSound (ellie) def blockingPlayInRange(sound,start,stop): if not isinstance(sound, Sound): print "blockingPlayInRange(sound,start,stop): Input is not a sound." raise ValueError sound.blockingPlayInRange(start,stop) #20June03 new functionality in JavaSound (ellie) def playAtRateInRange(sound,rate,start,stop): if not isinstance(sound, Sound): print "playAtRateInRAnge(sound,rate,start,stop): Input is not a sound." raise ValueError sound.playAtRateInRange(rate,start,stop) #20June03 new functionality in JavaSound (ellie) def blockingPlayAtRateInRange(sound,rate,start,stop): if not isinstance(sound, Sound): print "blockingPlayAtRateInRange(sound,rate,start,stop): Input is not a sound." raise ValueError sound.blockingPlayAtRateInRange(start,stop) def getSamplingRate(sound): if not isinstance(sound, Sound): print "getSamplingRate(sound): Input is not a sound." raise ValueError return sound.getSamplingRate() def setSampleValueAt(sound,index,value): if not isinstance(sound, Sound): print "setSampleValueAt(sound,index,value): Input is not a sound." raise ValueError sound.setSampleValue(index,value) def getSampleValueAt(sound,index): if not isinstance(sound, Sound): print "getSampleValueAt(sound,index): Input is not a sound." raise ValueError return sound.getSampleValue(index) def getSampleObjectAt(sound,index): if not isinstance(sound, Sound): print "getSampleObjectAt(sound,index): Input is not a sound." raise ValueError return sound.getSampleObjectAt(index) def setSample(sample,value): if not isinstance(sample, Sample): print "setSample(sample,value): Input is not a sample." raise ValueError # Need to coerce value to integer return sample.setValue(value) #AdamW May 2004: synonym for setSample to prevent confusion def setValue(sample, value): if not isinstance(sample, Sample): print "setvalue(sample,value): Input is not a sample." raise ValueError # Need to coerce value to integer return sample.setValue(value) # Alyce Brady: changed name from getSample to getSampleValue to make # for more readable user code. def getSampleValue(sample): if not isinstance(sample, Sample): print "getSample(sample): Input is not a sample." raise ValueError return sample.getValue() #AdamW May 2004: synonym for getSample to prevent confusion def getValue(sample): if not isinstance(sample, Sample): print "getValue(sample): Input is not a sample." raise ValueError return sample.getValue() def getSound(sample): if not isinstance(sample, Sample): print "getSound(sample): Input is not a sample." raise ValueError return sample.getSound() def getLength(sound): if not isinstance(sound, Sound): print "getLength(sound): Input is not a sound." raise ValueError return sound.getLength() def writeSoundTo(sound,filename): global mediaFolder if not os.path.isabs(filename): filename = mediaFolder + filename if not isinstance(sound, Sound): print "writeSoundTo(sound,filename): Input is not a sound." raise ValueError sound.writeTo(filename) ## ## IMAGE CLASSES ## class Picture: def __init__(self): self.pic=JavaPicture() # Alyce Brady: fixed to create image of dimensions width x height # rather than (width+1) x (height+1) and added extra parameter # to allow different background colors. def createImage(self, width, height, color): self.pic.createNewImage(width, height) self.addRectFilled(color, 1, 1, width, height) def loadImage(self,filename): global mediaFolder try: if not os.path.isabs(filename): filename = mediaFolder + filename if self.pic.loadImage(filename) == 0: print "load image failed." self.filename = filename except: exc_type, exc_value, exc_tb = sys.exc_info() print exc_type print exc_value print traceback.extract_tb(exc_tb) print "Was unable to load the image in "+ filename def __str__(self): return "Picture, filename "+self.filename+" height "+str(self.getHeight())+" width "+str(self.getWidth()) def repaint(self): self.pic.repaintImage() def show(self): self.pic.showPictureWithTitle(getShortPath(self.filename)) def setTitle(self, title): self.pic.setTitle(title) def getWidth(self): return self.pic.getWidth() def getHeight(self): return self.pic.getHeight() # Alyce Brady: added to provide a speedy cropping function def crop(self, upperLeftX, upperLeftY, width, height): realULX = upperLeftX - 1 realULY = upperLeftY - 1 width = min(width, self.getWidth() - realULX) height = min(height, self.getHeight() - realULY) newPict = makeEmptyPicture(width, height) # (Added new crop method to JavaPicture also.) self.pic.crop(newPict.pic, realULX, realULY, width, height) return newPict # Alyce Brady: added to provide a speedy picture copy function def copyInto(self, destPict, upperLeftX, upperLeftY): # (Added new copyInto method to JavaPicture also.) self.pic.copyInto(destPict.pic, upperLeftX - 1, upperLeftY - 1) def getPixel(self,x,y): return Pixel(self,x - 1,y - 1) # Alyce Brady: modified ranges to start at 0 to get 1st row and # 1st column of the picture. (x and y coordinates for Pixel # objects start at 0 even though the x and y parameters passed # to getPixel start at 1.) def getPixels(self): collect = [] for x in range(0,self.getWidth()): for y in range(0,self.getHeight()): collect.append(Pixel(self,x,y)) return collect def writeTo(self,filename): if not os.path.isabs(filename): filename = mediaFolder + filename self.pic.saveImage(filename) # Graphics stuff on pictures def addRectFilled(self,acolor,x,y,w,h): g = self.pic.bimg.getGraphics() g.setColor(acolor.getJcolor()) g.fillRect(x - 1,y - 1,w,h) def addRect(self, acolor,x,y,w,h): g = self.pic.bimg.getGraphics() g.setColor(acolor.getJcolor()) g.drawRect(x - 1,y - 1,w,h) def addOvalFilled(self, acolor,x,y,w,h): g = self.pic.bimg.getGraphics() g.setColor(acolor.getJcolor()) g.fillOval(x - 1,y - 1,w,h) def addOval(self, acolor,x,y,w,h): g = self.pic.bimg.getGraphics() g.setColor(acolor.getJcolor()) g.drawOval(x - 1,y - 1,w,h) def addArcFilled(self, acolor,x,y,w,h,start,angle): g = self.pic.bimg.getGraphics() g.setColor(acolor.getJcolor()) g.fillArc(x - 1,y - 1,w,h,start,angle) def addArc(self, acolor,x,y,w,h,start,angle): g = self.pic.bimg.getGraphics() g.setColor(acolor.getJcolor()) g.drawArc(x - 1,y - 1,w,h,start,angle) def addLine(self, acolor, x1, y1, x2, y2): g = self.pic.bimg.getGraphics() g.setColor(acolor.getJcolor()) g.drawLine(x1 - 1,y1 - 1,x2 - 1,y2 - 1) def addText(self, acolor, x, y, string): g = self.pic.bimg.getGraphics() g.setColor(acolor.getJcolor()) g.drawString(string, x - 1, y - 1) def addTextWithStyle(self, acolor, x, y, string, style): g = self.pic.bimg.getGraphics() g.setColor(acolor.getJcolor()) g.setFont(style) g.drawString(string, x - 1, y - 1) ## # Globals for styled text ## def makeStyle(fontName,emph,size): return jfont(fontName,emph,size) sansSerif = "SansSerif" serif = "Serif" mono = "Monospaced" italic = jfont.ITALIC bold = jfont.BOLD plain = jfont.PLAIN # # CLASS PIXEL # class Pixel: def __init__(self,picture,x,y): self.pixel = picture.pic.getPixel(x, y) def __str__(self): return "Pixel, color="+str(self.getColor()) def setRed(self,r): self.pixel.setRed(int(r)) def setGreen(self,g): self.pixel.setGreen(int(g)) def setBlue(self,b): self.pixel.setBlue(int(b)) def getRed(self): return self.pixel.getRed() def getGreen(self): return self.pixel.getGreen() def getBlue(self): return self.pixel.getBlue() def getColor(self): return Color(self.pixel.getColor()) def setColor(self,color): # Alyce Brady: modified to call setColor once rather than # separate calls to setRed, setGreen, setBlue (approx. # 25% speed-up in calls to global setColor function). self.pixel.setColor(color.getJcolor()) def setColorFrom(self,otherPixel): self.pixel.setColorFrom(otherPixel.pixel) def getX(self): return self.pixel.x + 1 def getY(self): return self.pixel.y + 1 # Alyce Brady: modified class to store java.awt.Color object as only # state and compute r, g, and b as needed. Constructor changed also, # to take a java.awt.Color object as its parameter. Finally, # commented out the modifier methods other than makeLighter and # makeDarker, to make Colors almost immutable. class Color: def __init__(self,javaColor): self.jc=javaColor def __str__(self): return "color r="+str(self.getRed())+" g="+str(self.getGreen())+" b="+str(self.getBlue()) def __eq__(self,newcolor): return self.jc == newcolor.jc def __ne__(self,newcolor): return not self == newcolor def distance(self,color): r = pow((self.getRed() - color.getRed()),2) g = pow((self.getGreen() - color.getGreen()),2) b = pow((self.getBlue() - color.getBlue()),2) return math.sqrt(r+g+b) def __sub__(self,color): return Color(jcolor(self.getRed()-color.getRed()),(self.getGreen()-color.getGreen()),(self.getBlue()-color.getBlue())) def difference(self,color): return self - color def getJcolor(self): return self.jc # def setJcolor(self, newcolor): # self.jc=newcolor def getRGB(self): return [self.getRed(), self.getGreen(), self.getBlue()] # def setRGB(self,atuple): # self.jc=jcolor(atuple[0], atuple[1], atuple[2]) def getRed(self): return self.jc.getRed() def getGreen(self): return self.jc.getGreen() def getBlue(self): return self.jc.getBlue() # def setRed(self,value): # self.jc=jcolor(value, self.getGreen(), self.getBlue()) # def setGreen(self,value): # self.jc=jcolor(self.getRed(), value, self.getBlue()) # def setBlue(self,value): # self.jc=jcolor(self.getRed(), self.getGreen(), value) # Alyce Brady: THIS SHOULD BE INACTIVATED ALSO! def makeLighter(self): self.jc = self.jc.brighter() # Alyce Brady: THIS SHOULD BE INACTIVATED ALSO! def makeDarker(self): self.jc = self.jc.darker() ## ## Global color functions ## def pickAColor(): # Alyce Brady: modified to use constant black rather than Color(0,0,0) import javax.swing choose = javax.swing.JColorChooser() jf = javax.swing.JFrame() jc = choose.showDialog(jf,"Choose a color",black.getJcolor()) print jc if jc != None: ncolor=Color(jc) return ncolor else: return black def makeColor(red,green,blue): # Alyce Brady: modified to include adjustment of r,g,b values passed # as parameters to 0..255 range (previously in Color constructor) and # to use new Color constructor that takes a Java color. red = int(red) if red < 0: while(red<0): red = 256 + red if red > 255: while(red>255): red = red - 256 green = int(green) if green < 0: while(green<0): green = 256 + green if green > 255: while(green>255): green = green - 256 blue = int(blue) if blue < 0: while(blue<0): blue = 256 + blue if blue > 255: while(blue>255): blue = blue - 256 return Color(jcolor(red,green,blue)) def makeDarker(color): if not isinstance(color, Color): print "makeDarker(color): Input is not a color." raise ValueError color.makeDarker() # Alyce Brady: it would be better if the line above were # color.getJcolor().darker(), to prevent darkening color # constants, but this would invalidate the function # description on p. 49 of the textbook. return color def makeLighter(color): if not isinstance(color, Color): print "makeLighter(color): Input is not a color." raise ValueError color.makeLighter() # Alyce Brady: it would be better if the line above were # color.getJcolor().brighter(), to prevent brightening color # constants, but this would invalidate the function # description on p. 49 of the textbook. return color #Constants # (modified by Alyce Brady to use makeColor function) black = makeColor(0,0,0) white = makeColor(255,255,255) blue = makeColor(0,0,255) red = makeColor(255,0,0) green = makeColor(0,255,0) gray = makeColor(128,128,128) darkGray = makeColor(64,64,64) lightGray = makeColor(192,192,192) yellow = makeColor(255,255,0) orange = makeColor(255,200,0) pink = makeColor(255,175,175) magenta = makeColor(255,0,255) cyan = makeColor(0,255,255) ## ## Global picture functions ## def makePicture(filename): global mediaFolder if not os.path.isabs(filename): filename = mediaFolder + filename if not os.path.isfile(filename): print "makePicture(filename): There is no file at "+filename raise ValueError picture = Picture() picture.loadImage(filename) try: w = picture.getWidth() return picture except: print "Was unable to load the image in " + filename +"\nMake sure it's a valid image file." # Alyce Brady: added new optional parameter to allow for empty pictures with # different background colors. def makeEmptyPicture(width, height, color = black): picture = Picture() picture.createImage(width, height, color) picture.filename = '' return picture def getPixels(picture): if not isinstance(picture, Picture): print "getPixels(picture): Input is not a picture" raise ValueError return picture.getPixels() # Alyce Brady: Added function with name that is easier to distinguish # from getPixel. def getAllPixels(picture): return getPixels(picture) def getWidth(picture): if not isinstance(picture, Picture): print "getWidth(picture): Input is not a picture" raise ValueError return picture.getWidth() def getHeight(picture): if not isinstance(picture, Picture): print "getHeight(picture): Input is not a picture" raise ValueError return picture.getHeight() # Alyce Brady: Added function that crops a picture in roughly 1/10th # the time it would take using getPixel/setColor in nested for-loops. def crop(picture, upperLeftX, upperLeftY, width, height): if not isinstance(picture, Picture): print "crop(picture, x, y, width, height): First parameter is not a picture" raise ValueError return picture.crop(upperLeftX, upperLeftY, width, height) # Alyce Brady: Added function that duplicates a picture in roughly 1/10th # the time it would take using getPixel/setColor in nested for-loops. def duplicate(origPict): newPict = makeEmptyPicture(getWidth(origPict), getHeight(origPict)) copyInto(origPict, newPict, 1, 1) return newPict # Alyce Brady: Added function that copies a picture into a (presumably) # larger canvas in roughly 1/10th the time it would take using # getPixel/setColor in nested for-loops. def copyInto(origPict, destPict, upperLeftX, upperLeftY): if not isinstance(origPict, Picture): print "copyInto(origPict, destPict, x, y): First parameter is not a picture" raise ValueError if not isinstance(destPict, Picture): print "copyInto(origPict, destPict, x, y): Second parameter is not a picture" raise ValueError return origPict.copyInto(destPict, upperLeftX, upperLeftY) def show(picture, title=None): #picture.setTitle(getShortPath(picture.filename)) #if title <> None: #picture.setTitle(title) if not isinstance(picture, Picture): print "show(picture): Input is not a picture" raise ValueError picture.show() def repaint(picture): if not isinstance(picture, Picture): print "repaint(picture): Input is not a picture" raise ValueError picture.repaint() def addLine(picture,x1,y1,x2,y2): if not isinstance(picture, Picture): print "addLine(picture,x1,y1,x2,y2): Input is not a picture" raise ValueError picture.addLine(black,x1,y1,x2,y2) def addText(picture,x1,y1,string): if not isinstance(picture, Picture): print "addText(picture,x1,y1,string): Input is not a picture" raise ValueError picture.addText(black,x1,y1,string) def addRect(picture,x,y,w,h): if not isinstance(picture, Picture): print "addRect(picture,x,y,w,h): Input is not a picture" raise ValueError picture.addRect(black,x,y,w,h) def addRectFilled(picture,x,y,w,h,acolor): if not isinstance(picture, Picture): print "addRectFilled(picture,x,y,w,h,acolor): Input is not a picture" raise ValueError picture.addRectFilled(acolor,x,y,w,h) def getPixel(picture,x,y): if not isinstance(picture, Picture): print "getPixel(picture,x,y): Input is not a picture" raise ValueError return picture.getPixel(x,y) # Alyce Brady: Added range checking for 2nd parameter. def setRed(pixel,value): if not isinstance(pixel, Pixel): print "setRed(pixel,value): Input is not a pixel" raise ValueError if value < 0 or value > 255: print "setRed(pixel,value): Value is not between 0 and 255" raise ValueError pixel.setRed(value) def getRed(pixel): if not isinstance(pixel, Pixel): print "getRed(pixel): Input is not a pixel" raise ValueError return pixel.getRed() # Alyce Brady: Added range checking for 2nd parameter. def setBlue(pixel,value): if not isinstance(pixel, Pixel): print "setBlue(pixel,value): Input is not a pixel" raise ValueError if value < 0 or value > 255: print "setBlue(pixel,value): Value is not between 0 and 255" raise ValueError pixel.setBlue(value) def getBlue(pixel): if not isinstance(pixel, Pixel): print "getBlue(pixel): Input is not a pixel" raise ValueError return pixel.getBlue() # Alyce Brady: Added range checking for 2nd parameter. def setGreen(pixel,value): if not isinstance(pixel, Pixel): print "setGreen(pixel,value): Input is not a pixel" raise ValueError if value < 0 or value > 255: print "setGreen(pixel,value): Value is not between 0 and 255" raise ValueError pixel.setGreen(value) def getGreen(pixel): if not isinstance(pixel, Pixel): print "getGreen(pixel): Input is not a pixel" raise ValueError return pixel.getGreen() def getColor(pixel): if not isinstance(pixel, Pixel): print "getColor(pixel): Inputis not a pixel" raise ValueError return pixel.getColor() def setColor(pixel,color): if not isinstance(pixel, Pixel): print "setColor(pixel,color): Input is not a pixel." raise ValueError if not isinstance(color, Color): print "setColor(pixel,color): Input is not a color." raise ValueError pixel.setColor(color) def copyColor(fromPixel,toPixel): if not isinstance(fromPixel, Pixel) or not isinstance(toPixel, Pixel): print "copyColor(fromPixel,toPixel): Input is not two pixels." raise ValueError toPixel.setColorFrom(fromPixel) def getX(pixel): if not isinstance(pixel, Pixel): print "getX(pixel): Input is not a pixel" raise ValueError return pixel.getX() def getY(pixel): if not isinstance(pixel, Pixel): print "getY(pixel): Input is not a pixel" raise ValueError return pixel.getY() def distance(c1,c2): if not isinstance(c1, Color): print "distance(c1,c2): First input is not a color." raise ValueError if not isinstance(c2, Color): print "distance(c1,c2): Second input is not a color." raise ValueError return c1.distance(c2) def writePictureTo(pict,filename): global mediaFolder if not os.path.isabs(filename): filename = mediaFolder + filename if not isinstance(pict, Picture): print "writePictureTo(pict,filename): Input is not a picture" raise ValueError pict.writeTo(filename) if not os.path.exists(filename): print "writePictureTo(pict,filename): Path is not valid" raise ValueError ## # Java Music Interface ## def playNote(note, duration, intensity=64): JavaMusic.playNote(note, duration, intensity) ## # General user tools # def pickAFile(): global _lastFilePath import javax.swing if _lastFilePath != None and os.path.exists(_lastFilePath): choose = javax.swing.JFileChooser(_lastFilePath) else: choose = javax.swing.JFileChooser() choose.setDialogTitle("Pick A File") jf = javax.swing.JFrame() jf.getContentPane().add(choose) retValue = choose.showOpenDialog(jf) if retValue == 0: path = choose.getSelectedFile().getAbsolutePath() _lastFilePath = os.path.dirname(path) return path else: return "" def pickAFolder(): global _lastFilePath import javax.swing if _lastFilePath != None and os.path.exists(_lastFilePath): choose = javax.swing.JFileChooser(_lastFilePath) else: choose = javax.swing.JFileChooser() choose.setDialogTitle("Pick A Folder") choose.setFileSelectionMode(javax.swing.JFileChooser.DIRECTORIES_ONLY) choose.setFileHidingEnabled(1) jf = javax.swing.JFrame() jf.getContentPane().add(choose) retValue = choose.showOpenDialog(jf) if retValue == 0: path = choose.getSelectedFile().getAbsolutePath() _lastFilePath = path return path else: return "" def quit(): sys.exit(0) ## # MediaTools interface # def openPictureTool(picture): import PictureViewer viewer = PictureViewer(picture.pic) viewer.changeToBaseOne(); viewer.setTitle(getShortPath(picture.filename)) def openSoundTool(sound): import SoundView viewer = SoundView(sound.s, 0) try: viewer.setTitle(getShortPath(sound.filename)) except: viewer.setTitle("No File Name") ## # Movie Functions # def makeMovieFromPictures(frames, outputpath, framerate=30): global mediaFolder filename = outputpath try: import JpegImagesToMovie if not os.path.isabs(outputpath): outputpath = mediaFolder + outputpath vec = java.util.Vector() width = frames[0].getWidth() height = frames[0].getHeight() for f in frames: vec.addElement(f.pic) if os.path.exists(filename): os.remove(filename) jitm = JpegImagesToMovie() suc = jitm.doItPath(width, height, framerate, vec, outputpath) if not suc: print "Could not write movie to " + outputpath print "Make sure that the mov path is valid and the pictures are in a list" else: print "Finished writing movie: " + outputpath jitm = None vec = None import java.lang.System as System System.gc() except Exception, e: print "Could not write movie to " + outputpath print "Make sure that the mov path is valid and the pictures are in a list" def openMovie(filename): global mediaFolder import java.lang.System as System if not os.path.isabs(filename): filename = mediaFolder + filename if System.getProperty('os.name').find('Mac') <> -1: print "Movie playback unsupported on Macintosh systems" elif not os.path.exists(filename): print "There is no movie at " + filename else: try: import quicktime import quicktime.io import quicktime.std.movies import quicktime.app.display.QTCanvas import quicktime.app.players.QTPlayer quicktime.QTSession.open() frame = swing.JFrame(os.path.basename(filename)) qtf = quicktime.io.QTFile(filename) movieFile = quicktime.io.OpenMovieFile.asRead(qtf) m = quicktime.std.movies.Movie.fromFile(movieFile) mc = quicktime.std.movies.MovieController(m) mc.setKeysEnabled(1) myQTCanvas = quicktime.app.display.QTCanvas() frame.getContentPane().add(myQTCanvas) myQTPlayer = quicktime.app.players.QTPlayer(mc) myQTCanvas.setClient(myQTPlayer, 1) frame.pack() frame.show() frame.toFront() except Exception, e: print e print "Could not open a player for " + filename print "Make sure it is a valid movie file."