# Lab: Copying a Picture Into a Bigger Picture And Scaling Pictures

## Introduction

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.

## Part 1: Copying a picture into a bigger picture

1. The following unfinished function, `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 newCanvas

```
The 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 notfit in canvas Picture could fit incanvas, but overhangs it

2. Write a new `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?

3. Sometimes pictures are framed with a wide matte and a second, much thinner matte of a contrasting color immediately around the picture. If you have time, you may want to try creating a double-matte effect.

## Part 2: Scaling and Tiling

1. The following function scales a picture down to one-quarter of its original size. It uses every other pixel of the original picture. Copy this function and test that it works the way you would expect.
```
# 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
```
2. This next function will tile a picture onto a canvas as many times as it can. Copy this function and test it with pictures and canvases of different sizes.
```# 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
```
3. Write a function, `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.)

## Submit your results

1. Submit the file containing your functions via .

## Post your results

1. Create a new web page for this lab. On it, display one matted image and one picture obtained from calling the `tileWithQuarter` function, along with descriptions for both of these.

2. Copy your web page and the new images that should be on it to your personal web space on `kzoo.edu`. (You may want to review the instructions in Lab 1 if you've forgotten how to do this.)
3. Include a link to this new web page from your course page. Bring up your course page in a web browser and test your link.