'''images.py Jed Yang, 2016-10-25 Skeleton file for HW10. Requires Pillow. https://python-pillow.org/ ''' import sys from PIL import Image ################################################################################ ## Sample Functions ## Everything you need is demonstrated here. ########### ################################################################################ def getRedImage(originalImage): '''Returns a copy of originalImage where green and blue are removed. This function demonstrates how to - make a copy of the image given (so we don't muck it up), - load the pixels into a variable (so we can manipulate them), - loop through all pixels, and - set all the green and blue values to 0 (so only red parts remain). ''' # make a copy so we don't affect the original image redImage = originalImage.copy() width = redImage.width height = redImage.height # loads the pixels so we can manipulate them px = redImage.load() # loop through all the pixels for x in range(width): for y in range(height): redValue = px[x,y][0] # retains the R of RGB value but nukes G and B to 0 px[x,y] = (redValue, 0, 0) return redImage def getSmallImage(originalImage): '''Returns a smaller copy of originalImage. This function demonstrates how to create a new image of a different size. ''' size = originalImage.size # size[0] is originalImage.width # size[1] is originalImage.height newWidth = size[0] // 2 newHeight = size[1] // 2 # create a new image with different dimensions # http://pillow.readthedocs.io/en/3.4.x/reference/Image.html#PIL.Image.new scaledImage = Image.new("RGB", (newWidth, newHeight)) # loads the pixels so we can manipulate them pxOriginal = originalImage.load() pxScaled = scaledImage.load() for x in range(newWidth): for y in range(newHeight): pxScaled[x,y] = pxOriginal[2*x, 2*y] return scaledImage ################################################################################ ## Basic Image Manipulations ## Implement these functions. ################# ################################################################################ def getGrayImage(originalImage): '''Returns a copy of originalImage in black-and-white. A colour is a shade of gray if its red, green, and blue values are all equal. ''' return originalImage def getNegativeImage(originalImage): '''Returns a copy of originalImage converted to "negative" form (like a photographic negative). Here, you don't necessarily have to duplicate precisely the same technical visual effects that a photonegative actually uses. But you should modify all colours in a way that turns black into white, white into black, dark colours into light, light into dark, etc. ''' return originalImage def getMirrorImage(originalImage): '''Returns a copy of originalImage, mirrored.''' return originalImage def getRotatedImage(originalImage): '''Returns a copy of originalImage, rotated by 90 degrees (counter-clockwise). Your code should work on images that are not necessarily a square. As such, you would need to allocate a new image with width and height swapped. See getSmallImage for an idea of how to do that. ''' return originalImage def getScaledImage(originalImage, scaling): '''Returns a scaled copy of originalImage. If scaling is 2, for example, each side of your new image should be double the size of the original. Likewise, if scaling is 0.25, each side of your new image should be 1/4 the size of the original. If scaling factor is less than or equal to 0, do no image work at all and return None. Otherwise, return the new image. ''' return originalImage ################################################################################ ## Vacation Challenge ## First make sure your code above is working. ####### ################################################################################ def changeBlackboard(originalImage, red, green, blue): '''Returns a copy of originalImage where all "blackboard" pixels are replaced by the colour specified by the supplied red, green, and blue values. The trick here is to decide what it means for a pixel to be part of the "blackboard" (in terms of its RGB values). ''' return originalImage def vacationImage(blackboardImage, backgroundImage): '''Returns a copy of the first image where the blackboard is replaced by some more pleasing background. More specifically, replace all "blackboard" pixels in blackboardImage with pixels taken from backgroundImage. If your new image is the size of blackboardImage, you may use only a portion of backgroundImage. Alternatively, you can place blackboardImage into backgroundImage somewhere. You may assume that backgroundImage is at least as big as blackboardImage. ''' return blackboardImage def main(): # Complain (and exit) if there is no command line argument. if len(sys.argv) <= 1: print('Usage: python3 {0} '.format(sys.argv[0])) sys.exit(1) # Use the command line argument as the main testing image. filename = sys.argv[1] myImage = Image.open(filename) myImage.show() #################### ## Sample Functions redImage = getRedImage(myImage) redImage.show() # You can use the following to save the image. Beware, this process is a # little slow. # redImage.save('red.jpg') smallImage = getSmallImage(myImage) smallImage.show() ############################# ## Basic Image Manipulations grayImage = getGrayImage(myImage) # grayImage.show() negativeImage = getNegativeImage(myImage) # negativeImage.show() mirrorImage = getMirrorImage(myImage) # mirrorImage.show() rotatedImage = getRotatedImage(myImage) # rotatedImage.show() scaledImage = getScaledImage(myImage, 3) # scaledImage.show() if __name__ == '__main__': main()