The objective of this lab is to learn how to perform more complicated image manipulations by copying a picture into another picture, and scaling a picture.
copyInto
, takes
as its input a picture to be copied, a blank
canvas (an empty picture) in which to copy it, and the upper left x
and y coordinates of the location on the canvas where you want to copy
the picture.
def copyInto(picture, canvas, upperLeftX, upperLeftY): # Assign values to the variables widthToCopy and heightToCopy # based on whether or not there is room on the canvas to fit the # entire picture. If there isn't enough room, we should copy less # than the full width and height of the picture. #canvas argument will not be modified... newCanvas = duplicatePicture(canvas) pictureWidth = getWidth(picture) pictureHeight = getHeight(picture) canvasWidth = getWidth(newCanvas) canvasHeight = getHeight(newCanvas) #These two lines only work if the picture doesn't spill off the canvas... widthToCopy = pictureWidth heightToCopy = pictureHeight #You need something like the following two lines instead. #(You'll need to replace the question marks.) #widthToCopy = min(pictureWidth, ???????????) #heightToCopy = min(pictureHeight, ??????????) # Copy however much of the picture as will fit over to the canvas edge targetX = upperLeftX for sourceX in range(widthToCopy): targetY = upperLeftY for sourceY in range(heightToCopy): # Copy the color of the pixel at the source location to the # destination location. sourcePix = getPixel(picture, sourceX, sourceY) color = getColor(sourcePix) destPix = getPixel(newCanvas, targetX, targetY) setColor(destPix, color) targetY = targetY + 1 targetX = targetX +1 return newCanvasThe function as written so far only works if there is enough room on the canvas to copy the entire picture starting at the location you specify, as in the first illustration below. This is not always a safe assumption. The picture might be bigger than the canvas in at least one dimension, as in the second illustration, or it might be small enough to fit in the canvas but not when the copying starts at the specified upper-left corner, as in the third illustration. (In the illustrations, the black area represents the canvas in which we wish to copy the picture; any part of the picture covered with grid lines cannot be copied into the canvas.)
Design Questions: How
can you determine how much room is available in the canvas if you
start copying the picture at location (upperLeftX,
upperLeftY
)? In other words, how can you determine the width
of the space available from the specified upper left corner to the
edge of the canvas? How can you determine the height of the space
available from the same location?
Analysis Questions: Must the canvas be a blank empty picture? Could you also use this function to copy a picture onto another (non-blank) picture?Modify the function so that it only copies as much of the original or source picture as there is room for. To do this, use the
min
function to find the smaller of the two values
- the width of the picture, and the space available on the canvas.
Modify
the widthToCopy
variable to refer to this value.
(Alternatively, you could use an if
statement to do this: compare the width of the picture
with the space available on the canvas. If the space available
is smaller than the picture width, modify the widthToCopy
variable
to refer to the remaining width of the canvas instead.) Do something similar for
heightToCopy
. After you have adjusted the width and height
(if needed), the code above
will copy the picture (or however much will fit) to the canvas.
Make sure to comment your function appropriately.
![]() |
![]() |
![]() |
Picture fits in canvas | Picture does not fit in canvas |
Picture could fit in canvas, but overhangs it |
matte
function that takes two parameters, a
picture and a matte width, and creates a new picture consisting of the
original picture surrounded by a matte of the appropriate width. (A
matte is the sheet of cardboard or thick paper that often forms a border
around a picture inside a frame.) The function should return the
new picture with the matte. You may write your function so that it
always creates a black matte, as in the examples below, or, if you have
time, you may wish to add an extra parameter that specifies the matte color.
Design Questions: Do you have other functions you can use to make writing this function easier? If you have the original picture and know the width of the matte on all sides of the picture, how should you compute the dimensions of the new picture with the matte? Where should the original picture be placed in the new picture? How should you specify that?
![]() |
![]() |
![]() |
# Returns a new picture 1/4 the size of the # original picture (half as wide and half as high). def quarter(orig): #Get the original width and height and divide them in half newWidth = getWidth(orig)/2 newHeight = getHeight(orig)/2 #Make an empty picture to store the scaled image newCanvas = makeEmptyPicture(newWidth,newHeight) #Copy every other pixel onto the new canvas for targetX in range(newWidth): for targetY in range(newHeight): color = getColor(getPixel(orig, targetX*2, targetY*2)) setColor(getPixel(newCanvas, targetX, targetY), color) return newCanvas
# Fills a canvas with as many copies of a picture as will # fit, including partial copies of the picture along the # right and lower edges if necessary def tile(picture, canvas): for targetY in range(0, getHeight(canvas),getHeight(picture)): for targetX in range(0, getWidth(canvas), getWidth(picture)): canvas = copyInto(picture, canvas, targetX, targetY) return canvas
tileWithQuarters
, that takes a
picture as a parameter. It should create a new picture the same size as
the
original picture, and tile four copies of the original image, scaled to
1/4-size. This function should return the new picture.
(Hint: There are at least two ways to do this - you may use your
tile
function or you may
think about how to use the copyInto
function to do this.)
tileWithQuarter
on Kit.