chapter 6: modifying pixels by position
DESCRIPTION
Chapter Learning GoalsTRANSCRIPT
![Page 1: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/1.jpg)
Chapter 6: Modifying Pixels by Position
![Page 2: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/2.jpg)
![Page 3: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/3.jpg)
![Page 4: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/4.jpg)
There are four conditional statements in this program for turning the red flowers in the arch into moon-colored flowers.
One of the generated this image. Which one?
![Page 5: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/5.jpg)
Pixels are in a matrixMatrices have two dimensions: A height and
a widthWe can reference any element in the matrix
with (x,y) or (horizontal, vertical)We refer to those coordinates as index
numbers or indicesWe sometimes want to know where a pixel is,
and getPixels doesn't let us know that.
![Page 6: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/6.jpg)
![Page 7: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/7.jpg)
Pixels in a Matrix
>>> h = makePicture("horse.jpg")>>> print getHeight(h)640>>> print getWidth(h)480>>> print getPixel(h,0,0)Pixel red=62 green=78 blue=49>>> print getPixel(h,479,639)Pixel red=113 green=89 blue=77>>> print getPixel(h,480,640)getPixel(picture,x,y): x (= 480) is less than 0 or bigger than the width (= 479)The error was:Inappropriate argument value (of correct type).An error occurred attempting to pass an argument to a function.
![Page 8: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/8.jpg)
Indices from the function rangeRange returns a sequence between its first
two inputs, possibly using a third input as the increment
>>> print range(1,4)[1, 2, 3]>>> print range(-1,3)[-1, 0, 1, 2]>>> print range(1,10,2)[1, 3, 5, 7, 9]>>> print range(3)[0,1,2]
Notice:• End value is never included.• range(0,10) ends at 9.
• If you leave out a start value, it's assumed to be zero.
![Page 9: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/9.jpg)
Side Note:That thing in [] is a sequence>>> a=[1,2,3]>>> print a[1, 2, 3]>>> a = a + 4An attempt was made to call a function with a parameter of an invalid type>>> a = a + [4]>>> print a[1, 2, 3, 4]>>> a[0]1
We can assign names to sequences, print them, add items to sequences, and access individual pieces of them.
We can also use for loops to process each element of a sequence.
![Page 10: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/10.jpg)
We can use range to generate index numbersWe'll do this by working the range from 0 to the height-1, and 0 to the width-1.Using the range function will make it easy to
start from 0 and stop before the end value.But we'll need more than one loop.
Each for loop can only change one variable,and we need two for indexing a matrix
![Page 11: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/11.jpg)
Working the pixels by numberTo use range, we'll have to use nested loops
One to walk the width, the other to walk the height Be sure to watch your blocks (i.e., indentation) carefully!
def increaseRed2(picture): for x in range(0,getWidth(picture)): for y in range(0,getHeight(picture)): px = getPixel(picture,x,y) value = getRed(px) setRed(px,value*1.1)
![Page 12: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/12.jpg)
def increaseRed2(picture): for x in range(0,getWidth(picture)): for y in range(0,getHeight(picture)): px = getPixel(picture,x,y) value = getRed(px) setRed(px,value*1.1)
The first time through the first loop, x is the name for 0.
We'll be processing the first column of pixels in the picture.
![Page 13: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/13.jpg)
def increaseRed2(picture): for x in range(0,getWidth(picture)): for y in range(0,getHeight(picture)): px = getPixel(picture,x,y) value = getRed(px) setRed(px,value*1.1)
Next, we set y to 0. We're now going to process each of the pixels in the first column.
![Page 14: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/14.jpg)
def increaseRed2(picture): for x in range(0,getWidth(picture)): for y in range(0,getHeight(picture)): px = getPixel(picture,x,y) value = getRed(px) setRed(px,value*1.1)
With x = 0 and y = 0, we get the leftmost pixel and increase its red by 10%
![Page 15: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/15.jpg)
def increaseRed2(picture): for x in range(0,getWidth(picture)): for y in range(0,getHeight(picture)): px = getPixel(picture,x,y) value = getRed(px) setRed(px,value*1.1)
Next we set y to 1 (next value in the sequence range(0,getHeight(picture))
![Page 16: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/16.jpg)
def increaseRed2(picture): for x in range(0,getWidth(picture)): for y in range(0,getHeight(picture)): px = getPixel(picture,x,y) value = getRed(px) setRed(px,value*1.1)
x is still 0, and now y is 1, so increase the red for pixel (0,1)
We continue along this way, with y taking on every value from 0 to the height of the picture (minus 1).
![Page 17: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/17.jpg)
def increaseRed2(picture): for x in range(0,getWidth(picture)): for y in range(0,getHeight(picture)): px = getPixel(picture,x,y) value = getRed(px) setRed(px,value*1.1)
Now that we're done with the loop for y, we get back to the FOR loop for x.x takes on the value 1, and we go back to the y loop to process all the pixels in the column x=1.
![Page 18: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/18.jpg)
Lightening a Picture with Nested Loopsdef lighten2(picture): for x in range(0,getWidth(picture)): for y in range(0,getHeight(picture)): px = getPixel(picture,x,y) color = getColor(px) color = makeLighter(color) setColor(px,color)
![Page 19: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/19.jpg)
Which function did A?
A B
![Page 20: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/20.jpg)
Reducing Red Eye with Nested Loopsdef removeRedEye2(pic,sX,sY,eX,eY,endColor): for x in range(sX,eX): for y in range(sY,eY): px = getPixel(pic,x,y) if (distance(red,getColor(px)) < 165): setColor(px,endColor)
This version is far faster than the previous version
![Page 21: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/21.jpg)
Timingfrom time import clock
def yellowbox1(pict): start = clock() for px in getPixels(pict): x = getX(px) y = getY(px) if 10 <= x < 20 and 10 <= y < 20: setColor(px,yellow) print "Time:",clock()-start
def yellowbox2(pict): start = clock() for x in range(10,20): for y in range(10,20): setColor(getPixel(pict,x,y),yellow) print "Time:",clock()-start
>>> b = makePicture("bridge.jpg")>>> bPicture, filename /Users/guzdial/Desktop/mediasources-4ed/bridge.jpg height 640 width 480>>> yellowbox1(b)Time: 1.317775>>> yellowbox2(b)Time: 0.00316000000001
![Page 22: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/22.jpg)
What can you do if you know where the pixels are? One answer: MirroringImagine a mirror horizontally across the
picture,or vertically
What would we see?How do generate that digitally?
We simply copy the colors of pixels from one place to another
![Page 23: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/23.jpg)
Work it out with matricesmirrorPoint is halfway across: getWidth(picture)/2
If left pixel is at (x,y), right pixel is at (width-x-1,y)
![Page 24: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/24.jpg)
def mirrorVertical(source): mirrorPoint = getWidth(source) / 2 width = getWidth(source) for y in range(0,getHeight(source)): for x in range(0,mirrorPoint): leftPixel = getPixel(source,x,y) rightPixel = getPixel(source,width - x - 1,y) color = getColor(leftPixel) setColor(rightPixel,color)
![Page 25: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/25.jpg)
def mirrorHorizontal(source): mirrorPoint = getHeight(source) / 2 height = getHeight(source) for x in range(0,getWidth(source)): for y in range(0,mirrorPoint): topPixel = getPixel(source,x,y) bottomPixel = getPixel(source,x,height - y - 1) color = getColor(topPixel) setColor(bottomPixel,color)
![Page 26: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/26.jpg)
Of course!
![Page 27: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/27.jpg)
What if we wanted to copy bottom to top?Very simple: Swap the order of pixels in the
bottom linesdef mirrorBotTop(source): mirrorPoint = getHeight(source) / 2 height = getHeight(source) for x in range(0,getWidth(source)): for y in range(0,mirrorPoint): topPixel = getPixel(source,x,y) bottomPixel = getPixel(source,x,height - y - 1) color = getColor(bottomPixel) setColor(topPixel,color)
![Page 28: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/28.jpg)
Mirroring bottom to top
![Page 29: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/29.jpg)
Doing something useful with mirroringMirroring can be used
to create interesting effects, but it can also be used to create realistic effects.
Consider this image from a trip to Athens, Greece.Can we “repair” the temple
by mirroring the complete part onto the broken part?
![Page 30: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/30.jpg)
Figuring out where to mirrorUse MediaTools to find the mirror point and
the range that we want to copy
![Page 31: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/31.jpg)
Writing functions for specific files…generallyThe function to mirror the temple needs
to work for one and only one file.But we still don't want to write out the
whole path.setMediaPath() allows us to pick a directory where our
media will be stored.getMediaPath(filename) will generate the entire path for
us to the filename in the media directoryTHIS ONLY WORKS WHEN WE'RE ACCESSING FILES
IN THE MEDIA DIRECTORY AND WHERE WE HAVE SET THE PATH FIRST!
![Page 32: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/32.jpg)
Some Utility FunctionsIf you know the name of the file, searching
for it with pickAFile() feels tediousYou can set and get a media folder (path) for
remembering a place where your media will be coming from (or going to)setMediaPath() lets you pick a file in your
media foldergetMediaPath(basefilename) lets you
generate a complete filename out of only the last part
![Page 33: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/33.jpg)
Example>>> setMediaPath()New media folder: C:\Documents and Settings\Mark Guzdial\My Documents\mediasources\>>> getMediaPath("barbara.jpg")'C:\\Documents and Settings\\Mark Guzdial\\My Documents\\mediasources\\barbara.jpg'>>> barb=makePicture(getMediaPath("barbara.jpg"))
![Page 34: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/34.jpg)
Program to mirror the templedef mirrorTemple(): source = makePicture(getMediaPath("temple.jpg")) mirrorPoint = 276 for x in range(13,mirrorPoint): for y in range(27,97): pleft = getPixel(source,x,y) pright = getPixel(source,mirrorPoint + mirrorPoint - 1 -
x,y) setColor(pright,getColor(pleft)) show(source) return source
![Page 35: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/35.jpg)
Did it really work?It clearly did the
mirroring, but that doesn't create a 100% realistic image.
Check out the shadows: Which direction is the sun coming from?
![Page 36: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/36.jpg)
Understanding the Temple FixWhat is the very first transfer of pixels from
and to? Which (x,y) pixel from? Which (x,y) pixel to?
What is second?How many pixels get copied?
![Page 37: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/37.jpg)
Adding print statements to see what's happeningdef mirrorTemple(): source = makePicture(getMediaPath("temple.jpg")) mirrorPoint = 276 for x in range(13,mirrorPoint): for y in range(27,97): print "Copying color from",x,y, " to ",mirrorPoint + mirrorPoint
- 1 - x, y pleft = getPixel(source,x,y) pright = getPixel(source,mirrorPoint + mirrorPoint - 1 - x,y) setColor(pright,getColor(pleft)) show(source) return source
![Page 38: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/38.jpg)
First pixels are either side of the mirrorpoint, then moving down>>>
p2=mirrorTemple()Copying color from
13 27 to 538 27Copying color from
13 28 to 538 28Copying color from
13 29 to 538 29
![Page 39: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/39.jpg)
Counting pixelsdef mirrorTemple(): source = makePicture(getMediaPath("temple.jpg")) mirrorPoint = 276 count = 0 for x in range(13,mirrorPoint): for y in range(27,97): pleft = getPixel(source,x,y) pright = getPixel(source,mirrorPoint + mirrorPoint - 1 - x,y) setColor(pright,getColor(pleft)) count = count + 1 show(source) print "We copied",count,"pixels" return source
![Page 40: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/40.jpg)
Counting pixels
Where did that come from?How many rows? Y goes from 27 to 97
= 70 rows of pixelsHow many columns? X goes from 13 to 276
= 263 columns of pixels70 * 263 = 18410
>>> p2=mirrorTemple()We copied 18410 pixels
![Page 41: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/41.jpg)
Which function did A?
A
![Page 42: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/42.jpg)
The same function below did the two pictures, but with one line difference. Which one did which picture?
A B
![Page 43: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/43.jpg)
Replacing colorsin a range
def turnRedInRange(): brown = makeColor(57,16,8) file=“/Users/guzdial/mediasources/barbara.jpg" picture=makePicture(file) for x in range(70,168): for y in range(56,190): px=getPixel(picture,x,y) color = getColor(px) if distance(color,brown)<50.0: redness=getRed(px)*1.5 setRed(px,redness) show(picture) return(picture)
Get the range using MediaTools
![Page 44: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/44.jpg)
Walking this codeLike last time: Don't need input, same color
we want to change, same file, make a picture
def turnRedInRange(): brown = makeColor(57,16,8) file=“/Users/guzdial/mediasources/barbara.jpg" picture=makePicture(file) for x in range(70,168): for y in range(56,190): px=getPixel(picture,x,y) color = getColor(px) if distance(color,brown)<50.0: redness=getRed(px)*1.5 setRed(px,redness) show(picture) return(picture)
![Page 45: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/45.jpg)
The nested loopI used MediaTools to find the rectangle where
most of the hair is that I want to change
def turnRedInRange(): brown = makeColor(57,16,8) file=“/Users/guzdial/mediasources/barbara.jpg“ picture=makePicture(file)
for x in range(70,168): for y in range(56,190): px=getPixel(picture,x,y) color = getColor(px) if distance(color,brown)<50.0: redness=getRed(px)*1.5 setRed(px,redness) show(picture) return(picture)
![Page 46: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/46.jpg)
Same thing as last time (could raise threshold now)Then we're looking for a close-match on
hair color, and increasing the redness
def turnRedInRange(): brown = makeColor(57,16,8) file=“/Users/guzdial/mediasources/barbara.jpg“ picture=makePicture(file) for x in range(70,168): for y in range(56,190):
px=getPixel(picture,x,y) color = getColor(px) if distance(color,brown)<50.0: redness=getRed(px)*1.5 setRed(px,redness) show(picture) return(picture)
![Page 47: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/47.jpg)
Could we do this without nested loops?Yes, but
complicated IF
def turnRedInRange2(): brown = makeColor(57,16,8) file=“/Users/guzdial/mediasources/barbara.jpg“ picture=makePicture(file) for p in getPixels(picture): x = getX(p) y = getY(p) if x >= 70 and x < 168: if y >=56 and y < 190: color = getColor(p) if distance(color,brown)<100.0: redness=getRed(p)*2.0 setRed(p,redness) show(picture) return picture
![Page 48: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/48.jpg)
Moving pixels across picturesWe've seen using index variables to track the
pixel position we're working with in a picture.We can copy between pictures, if we keep
track of: The source index variables
Where we're getting the pixels from The target index variables
Where we're putting the pixels at(Not really copying the pixels: Replicating
their color.)
![Page 49: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/49.jpg)
What can you do then?What can you do when copying from one
picture to another?Collages: Copy several pictures onto
oneCropping: You don't have to take the
whole pictureScaling: Make a picture smaller, or
larger when copying it
![Page 50: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/50.jpg)
Copying pixelsIn general, what we want to do is to keep
track of a sourceX and sourceY, and a targetX and targetY.We increment (add to them) in pairs
sourceX and targetX get incremented together sourceY and targetY get incremented together
The tricky parts are: Setting values inside the body of loops Incrementing at the bottom of loops
![Page 51: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/51.jpg)
Copying Barb to a canvasdef copyBarb(): # Set up the source and target pictures barbf=getMediaPath("barbara.jpg") barb = makePicture(barbf) canvasf = getMediaPath("7inX95in.jpg") canvas = makePicture(canvasf) # Now, do the actual copying targetX = 0 for sourceX in range(0,getWidth(barb)): targetY = 0 for sourceY in range(0,getHeight(barb)): color = getColor(getPixel(barb,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(barb) show(canvas) return canvas
![Page 52: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/52.jpg)
CommentsPython ignores from “# ” through the rest of
the lineIf you start a line with “# ”, the whole line is
ignoredWhy do we want lines to be ignored?
To be able to leave notes to ourselves or someone else about how the program works
![Page 53: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/53.jpg)
Walking through the copying functionFirst, get the source (barb) and target
(canvas) files and pictures as names we can use later.def copyBarb(): # Set up the source and target pictures barbf=getMediaPath("barbara.jpg") barb = makePicture(barbf) canvasf = getMediaPath("7inX95in.jpg") canvas = makePicture(canvasf) # Now, do the actual copying targetX = 0 for sourceX in range(0,getWidth(barb)): targetY = 0 for sourceY in range(0,getHeight(barb)): color = getColor(getPixel(barb,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(barb) show(canvas) return canvas
![Page 54: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/54.jpg)
We get the color of the pixel at sourceX and sourceY
We set (copy) the color to the pixel in the target picture at targetX and targetY
def copyBarb(): # Set up the source and target pictures barbf=getMediaPath("barbara.jpg") barb = makePicture(barbf) canvasf = getMediaPath("7inX95in.jpg") canvas = makePicture(canvasf)
# Now, do the actual copying targetX = 0 for sourceX in range(0,getWidth(barb)): targetY = 0 for sourceY in range(0,getHeight(barb)): color = getColor(getPixel(barb,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(barb) show(canvas) return canvas
![Page 55: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/55.jpg)
Setting up the copy looptargetX gets set to 0
at the beginningsourceX will range
across the width of the source picture
INSIDE the loop, we set targetY to 0 Inside because we want
it to start at 0 each time we do a new X
sourceY will range from 0 to one less height of source
def copyBarb(): # Set up the source and target pictures barbf=getMediaPath("barbara.jpg") barb = makePicture(barbf) canvasf = getMediaPath("7inX95in.jpg") canvas = makePicture(canvasf)
# Now, do the actual copying targetX = 0 for sourceX in range(0,getWidth(barb)): targetY = 0 for sourceY in range(0,getHeight(barb)): color = getColor(getPixel(barb,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(barb) show(canvas) return canvas
![Page 56: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/56.jpg)
Just before we end the sourceY loop, we increment targetY It's now set up for the
next time through the loop
It's set correctly for the next value of sourceY
Just before we end the sourceX loop, we increment the targetX Note carefully the
indentation to figure out which goes with which loop
def copyBarb(): # Set up the source and target pictures barbf=getMediaPath("barbara.jpg") barb = makePicture(barbf) canvasf = getMediaPath("7inX95in.jpg") canvas = makePicture(canvasf)
# Now, do the actual copying targetX = 0 for sourceX in range(0,getWidth(barb)): targetY = 0 for sourceY in range(0,getHeight(barb)): color = getColor(getPixel(barb,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(barb) show(canvas) return canvas
![Page 57: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/57.jpg)
What's this naming something as itself?targetX = targetX + 1This isn't really naming something as itself
targetX + 1 is evaluated It will result in the number after targetX
targetX = then sets the value of targetXThe result is that targetX gets incremented
by 1
![Page 58: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/58.jpg)
At the very end, we show the source and target
And return the modified target.
def copyBarb(): # Set up the source and target pictures barbf=getMediaPath("barbara.jpg") barb = makePicture(barbf) canvasf = getMediaPath("7inX95in.jpg") canvas = makePicture(canvasf)
# Now, do the actual copying targetX = 0 for sourceX in range(0,getWidth(barb)): targetY = 0 for sourceY in range(0,getHeight(barb)): color = getColor(getPixel(barb,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(barb) show(canvas) return canvas
![Page 59: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/59.jpg)
Works either waydef copyBarb2(): # Set up the source and target pictures barbf=getMediaPath("barbara.jpg") barb = makePicture(barbf) canvasf = getMediaPath("7inX95in.jpg") canvas = makePicture(canvasf) # Now, do the actual copying sourceX = 0 for targetX in range(0,getWidth(barb)): sourceY = 0 for targetY in range(0,getHeight(barb)): color =
getColor(getPixel(barb,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY),
color) sourceY = sourceY + 1 sourceX = sourceX + 1 show(barb) show(canvas) return canvas
As long as we increment sourceX and targetX together, and sourceY and targetY together, it doesn't matter which is in the for loop and which is incremented via expression
![Page 60: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/60.jpg)
Copying into the middle of the canvasdef copyBarbMidway(): # Set up the source and target pictures barbf=getMediaPath("barbara.jpg") barb = makePicture(barbf) canvasf = getMediaPath("7inX95in.jpg") canvas = makePicture(canvasf) # Now, do the actual copying targetX = 100 for sourceX in range(0,getWidth(barb)): targetY = 100 for sourceY in range(0,getHeight(barb)): color = getColor(getPixel(barb,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(barb) show(canvas) return canvas
![Page 61: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/61.jpg)
Copying a Horse to a Canvasdef copyHorse(): # Set up the source and target pictures src = makePicture("horse.jpg") canvas = makeEmptyPicture(1000,1000) # Now, do the actual copying targetX = 0 for sourceX in range(0,getWidth(src)): targetY = 0 for sourceY in range(0,getHeight(src)): color = getColor(getPixel(src,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(src) show(canvas) return canvas
![Page 62: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/62.jpg)
Copying another waydef copyHorse2(): # Set up the source and target pictures src = makePicture("horse.jpg") canvas = makeEmptyPicture(1000,1000) # Now, do the actual copying sourceX = 0 for targetX in range(0,getWidth(src)): sourceY = 0 for targetY in range(0,getHeight(src)): color = getColor(getPixel(src,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) sourceY = sourceY + 1 sourceX = sourceX + 1 show(src) show(canvas) return canvas
![Page 63: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/63.jpg)
Copying to a new Locationdef copyHorseMidway(): # Set up the source and target pictures src = makePicture("horse.jpg") canvas = makeEmptyPicture(1000,1000) # Now, do the actual copying targetX = 100 for sourceX in range(0,getWidth(src)): targetY = 200 for sourceY in range(0,getHeight(src)): color = getColor(getPixel(src,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(src) show(canvas) return canvas
![Page 64: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/64.jpg)
Cropping just the Facedef copyHorseFace(): # Set up the source and target pictures src = makePicture("horse.jpg") canvas = makeEmptyPicture(1000,1000) # Now, do the actual copying targetX = 100 for sourceX in range(104,267): targetY = 200 for sourceY in range(114,422): color = getColor(getPixel(src,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 #show(src) show(canvas) return canvas
![Page 65: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/65.jpg)
Same cropping, different loopsdef copyHorseFace2(): # Set up the source and target pictures src=makePicture("horse.jpg") canvas = makeEmptyPicture(1000,1000) # Now, do the actual copying sourceX = 104 for targetX in range(100,100+163): sourceY = 114 for targetY in range(200,200+308): color = getColor(getPixel(src,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) sourceY = sourceY + 1 sourceX = sourceX + 1 show(canvas) return canvas
![Page 66: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/66.jpg)
Copying: How it worksHere's the initial
setup:
![Page 67: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/67.jpg)
Copying: How it works 2After incrementing
the sourceY and targetY once (whether in the for or via expression):
![Page 68: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/68.jpg)
Copying: How it works 3After yet another
increment of sourceY and targetY:
When we finish that column, we increment sourceX and targetX, and start on the next column.
![Page 69: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/69.jpg)
Copying: How it looks at the endEventually, we copy
every pixel
![Page 70: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/70.jpg)
Making a collageCould we do
something to the pictures we copy in? Sure! Could either apply
one of those functions before copying, or do something to the pixels during the copy.
Could we copy more than one picture! Of course! Make a collage!
![Page 71: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/71.jpg)
def createCollage(): flower1=makePicture(getMediaPath("flower1.jpg")) print flower1 flower2=makePicture(getMediaPath("flower2.jpg")) print flower2 canvas=makePicture(getMediaPath("640x480.jpg")) print canvas #First picture, at left edge targetX=0 for sourceX in range(0,getWidth(flower1)): targetY=getHeight(canvas)-getHeight(flower1)-5 for sourceY in range(0,getHeight(flower1)): px=getPixel(flower1,sourceX,sourceY) cx=getPixel(canvas,targetX,targetY) setColor(cx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1 #Second picture, 100 pixels over targetX=100 for sourceX in range(0,getWidth(flower2)): targetY=getHeight(canvas)-getHeight(flower2)-5 for sourceY in range(0,getHeight(flower2)): px=getPixel(flower2,sourceX,sourceY) cx=getPixel(canvas,targetX,targetY) setColor(cx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1
#Third picture, flower1 negated negative(flower1) targetX=200 for sourceX in range(0,getWidth(flower1)): targetY=getHeight(canvas)-getHeight(flower1)-5 for sourceY in range(0,getHeight(flower1)): px=getPixel(flower1,sourceX,sourceY) cx=getPixel(canvas,targetX,targetY) setColor(cx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1 #Fourth picture, flower2 with no blue clearBlue(flower2) targetX=300 for sourceX in range(0,getWidth(flower2)): targetY=getHeight(canvas)-getHeight(flower2)-5 for sourceY in range(0,getHeight(flower2)): px=getPixel(flower2,sourceX,sourceY) cx=getPixel(canvas,targetX,targetY) setColor(cx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1 #Fifth picture, flower1, negated with decreased red decreaseRed(flower1) targetX=400 for sourceX in range(0,getWidth(flower1)): targetY=getHeight(canvas)-getHeight(flower1)-5 for sourceY in range(0,getHeight(flower1)): px=getPixel(flower1,sourceX,sourceY) cx=getPixel(canvas,targetX,targetY) setColor(cx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1 show(canvas) return(canvas)
Page 170-171 (4ed edition)
![Page 72: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/72.jpg)
Can we make that easier?The collage code is
long, yet simple.It's the same thing
over-and-over.We can generalize
that copying loop, and with parameters, use it in many places.
def copy(source, target, targX, targY): targetX = targX for sourceX in
range(0,getWidth(source)): targetY = targY for sourceY in
range(0,getHeight(source)):
px=getPixel(source,sourceX,sourceY) tx=getPixel(target,targetX,targetY) setColor(tx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1
![Page 73: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/73.jpg)
Exact same collage!def createCollage2():
flower1=makePicture(getMediaPath("flower1.jpg"))
print flower1
flower2=makePicture(getMediaPath("flower2.jpg"))
print flower2
canvas=makePicture(getMediaPath("640x480.jpg"))
print canvas #First picture, at left edge
copy(flower1,canvas,0,getHeight(canvas)-getHeight(flower1)-5)
#Second picture, 100 pixels over
copy(flower2,canvas,100,getHeight(canvas)-getHeight(flower2)-5)
#Third picture, flower1 negated negative(flower1)
copy(flower1,canvas,200,getHeight(canvas)-getHeight(flower1)-5)
#Fourth picture, flower2 with no blue clearBlue(flower2)
copy(flower2,canvas,300,getHeight(canvas)-getHeight(flower2)-5)
#Fifth picture, flower1, negated with decreased red
decreaseRed(flower1)
copy(flower1,canvas,400,getHeight(canvas)-getHeight(flower2)-5)
return canvas
![Page 74: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/74.jpg)
![Page 75: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/75.jpg)
Bigger or Smaller?
Does this function make the src bigger or smaller on the canvas?
1.Increases size by 50%
2.Decreases size by 50%
3.Decreases size by 50% and skips some pixels in target
4.Increases size by 50% and skips some pixels in target
![Page 76: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/76.jpg)
>>> c = makePicture("caterpillar.jpg")>>> copyPicDifferent(c,c1,10,10)>>> explore(c1)>>> copyAnyPic(c,c1,10,10)>>> explore(c1)
![Page 77: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/77.jpg)
Transformation = Small changes in copyingMaking relatively small changes in this basic
copying program can make a variety of transformations.Change the targetX and targetY, and you copy
wherever you wantCropping: Change the sourceX and sourceY
range, and you copy only part of the program.Rotating: Swap targetX and targetY, and you
end up copying sidewaysScaling: Change the increment on sourceX and
sourceY, and you either grow or shrink the image.
![Page 78: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/78.jpg)
Copying face to small canvasdef copyHorseFaceSmall(): # Set up the source and target pictures src = makePicture("horse.jpg") canvas = makeEmptyPicture(163,308) # Now, do the actual copying targetX = 0 for sourceX in range(104,267): targetY = 0 for sourceY in range(114,422): color = getColor(getPixel(src,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(canvas) return canvas
![Page 79: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/79.jpg)
Changing while copyingdef copyHorseFaceSmallBlack(): hcol = makeColor(216,169,143) # Set up the source and target pictures src = makePicture("horse.jpg") canvas = makeEmptyPicture(163,308) # Now, do the actual copying targetX = 0 for sourceX in range(104,267): targetY = 0 for sourceY in range(114,422): color = getColor(getPixel(src,sourceX,sourceY)) if distance(color,hcol) < 40: setColor(getPixel(canvas,targetX,targetY), black) else: setColor(getPixel(canvas,targetX,targetY), color) targetY = targetY + 1 targetX = targetX + 1 show(canvas) return canvas
![Page 80: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/80.jpg)
Copying vs. Referencing>>> a = 100>>> b = a>>> print a,b100 100>>> b = 200>>> print a,b100 200>>> a = 300>>> print a,b300 200
![Page 81: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/81.jpg)
Referencing works differently>>> pictureBarb = makePicture("barbara.jpg")>>> pixel1 = getPixelAt(pictureBarb,0,0)>>> print pixel1Pixel red=168 green=131 blue=105>>> anotherpixel = pixel1>>> print anotherpixelPixel red=168 green=131 blue=105>>> setColor(pixel1,black)>>> print pixel1Pixel red=0 green=0 blue=0>>> print anotherpixelPixel red=0 green=0 blue=0
![Page 82: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/82.jpg)
Making a collageCould we do
something to the pictures we copy in? Sure! Could either apply
one of those functions before copying, or do something to the pixels during the copy.
Could we copy more than one picture! Of course! Make a collage!
![Page 83: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/83.jpg)
def createCollage(): flower1=makePicture(getMediaPath("flower1.jpg")) print flower1 flower2=makePicture(getMediaPath("flower2.jpg")) print flower2 canvas=makePicture(getMediaPath("640x480.jpg")) print canvas #First picture, at left edge targetX=0 for sourceX in range(0,getWidth(flower1)): targetY=getHeight(canvas)-getHeight(flower1)-5 for sourceY in range(0,getHeight(flower1)): px=getPixel(flower1,sourceX,sourceY) cx=getPixel(canvas,targetX,targetY) setColor(cx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1 #Second picture, 100 pixels over targetX=100 for sourceX in range(0,getWidth(flower2)): targetY=getHeight(canvas)-getHeight(flower2)-5 for sourceY in range(0,getHeight(flower2)): px=getPixel(flower2,sourceX,sourceY) cx=getPixel(canvas,targetX,targetY) setColor(cx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1
#Third picture, flower1 negated negative(flower1) targetX=200 for sourceX in range(0,getWidth(flower1)): targetY=getHeight(canvas)-getHeight(flower1)-5 for sourceY in range(0,getHeight(flower1)): px=getPixel(flower1,sourceX,sourceY) cx=getPixel(canvas,targetX,targetY) setColor(cx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1 #Fourth picture, flower2 with no blue clearBlue(flower2) targetX=300 for sourceX in range(0,getWidth(flower2)): targetY=getHeight(canvas)-getHeight(flower2)-5 for sourceY in range(0,getHeight(flower2)): px=getPixel(flower2,sourceX,sourceY) cx=getPixel(canvas,targetX,targetY) setColor(cx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1 #Fifth picture, flower1, negated with decreased red decreaseRed(flower1) targetX=400 for sourceX in range(0,getWidth(flower1)): targetY=getHeight(canvas)-getHeight(flower1)-5 for sourceY in range(0,getHeight(flower1)): px=getPixel(flower1,sourceX,sourceY) cx=getPixel(canvas,targetX,targetY) setColor(cx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1 show(canvas) return(canvas)
Page 91-92 (2ed edition)
![Page 84: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/84.jpg)
Can we make that easier?The collage code is
long, yet simple.It's the same thing
over-and-over.We can generalize
that copying loop, and with parameters, use it in many places.
def copy(source, target, targX, targY): targetX = targX for sourceX in
range(0,getWidth(source)): targetY = targY for sourceY in
range(0,getHeight(source)):
px=getPixel(source,sourceX,sourceY) tx=getPixel(target,targetX,targetY) setColor(tx,getColor(px)) targetY=targetY + 1 targetX=targetX + 1
![Page 85: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/85.jpg)
Exact same collage!def createCollage2():
flower1=makePicture(getMediaPath("flower1.jpg"))
print flower1
flower2=makePicture(getMediaPath("flower2.jpg"))
print flower2
canvas=makePicture(getMediaPath("640x480.jpg"))
print canvas #First picture, at left edge
copy(flower1,canvas,0,getHeight(canvas)-getHeight(flower1)-5)
#Second picture, 100 pixels over
copy(flower2,canvas,100,getHeight(canvas)-getHeight(flower2)-5)
#Third picture, flower1 negated negative(flower1)
copy(flower1,canvas,200,getHeight(canvas)-getHeight(flower1)-5)
#Fourth picture, flower2 with no blue clearBlue(flower2)
copy(flower2,canvas,300,getHeight(canvas)-getHeight(flower2)-5)
#Fifth picture, flower1, negated with decreased red
decreaseRed(flower1)
copy(flower1,canvas,400,getHeight(canvas)-getHeight(flower2)-5)
return canvas
![Page 86: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/86.jpg)
Rotating the copydef flipHorseSideways(): # Set up the source and target pictures src = makePicture("horse.jpg") canvas = makeEmptyPicture(1000,1000) # Now, do the actual copying targetX = 0 for sourceX in range(0,getWidth(src)): targetY = 0 for sourceY in range(0,getHeight(src)): color = getColor(getPixel(src,sourceX,sourceY)) # Change is here setColor(getPixel(canvas,targetY,targetX), color) targetY = targetY + 1 targetX = targetX + 1 show(canvas) return canvas
![Page 87: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/87.jpg)
Rotating: How it worksWe increment the
same, but we use targetX for the Y coordinate and targetY for the X coordinate
![Page 88: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/88.jpg)
Rotate: How it endsSame amount of
increment, even same values in the variables, but a different result.
![Page 89: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/89.jpg)
Doing a real rotation
def rotateHorseSideways(): # Set up the source and target pictures src = makePicture("horse.jpg") canvas = makeEmptyPicture(1000,1000) # Now, do the actual copying targetX = 0 width = getWidth(src) for sourceX in range(0,getWidth(src)): targetY = 0 for sourceY in range(0,getHeight(src)): color =
getColor(getPixel(src,sourceX,sourceY)) # Change is here setColor(getPixel(canvas,targetY,width -
targetX - 1), color) targetY = targetY + 1 targetX = targetX + 1 show(canvas) return canvas
![Page 90: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/90.jpg)
ScalingScaling a picture (smaller or larger) has to do
with sampling the source picture differentlyWhen we just copy, we sample every pixelIf we want a smaller copy, we skip some pixels
We sample fewer pixelsIf we want a larger copy, we duplicate some
pixels We over-sample some pixels
![Page 91: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/91.jpg)
Scaling the horse face downdef copyHorseFaceSmaller(): # Set up the source and target pictures src=makePicture("horse.jpg") canvas = makeEmptyPicture(82,155) # Now, do the actual copying sourceX = 104 for targetX in range(0,int(163/2)): sourceY = 114 for targetY in range(0,int(308/2)): color = getColor(getPixel(src,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) sourceY = sourceY + 2 sourceX = sourceX + 2 show(canvas) return canvas
![Page 92: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/92.jpg)
Scaling the picture downdef copyBarbsFaceSmaller(): # Set up the source and target pictures barbf=getMediaPath("barbara.jpg") barb = makePicture(barbf) canvasf = getMediaPath("7inX95in.jpg") canvas = makePicture(canvasf) # Now, do the actual copying sourceX = 45 for targetX in range(100,100+((200-45)/2)): sourceY = 25 for targetY in range(100,100+((200-25)/2)): color = getColor(getPixel(barb,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY), color) sourceY = sourceY + 2 sourceX = sourceX + 2 show(barb) show(canvas) return canvas
![Page 93: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/93.jpg)
Scaling Up: Growing the pictureTo grow a picture, we
simply duplicate some pixels
We do this by incrementing by 0.5, but only use the integer part.
>>> print int(1)1>>> print int(1.5)1>>> print int(2)2>>> print int(2.5)2
![Page 94: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/94.jpg)
Scaling up
def copyHorseLarger(): # Set up the source and target pictures src = makePicture("horse.jpg") w = getWidth(src) h = getHeight(src) canvas = makeEmptyPicture(w*2,h*2) srcPixels = getPixels(src) trgPixels = getPixels(canvas) trgIndex = 0 # Now, do the actual copying for pixel in srcPixels: color = getColor(pixel) # Once trgPixel = trgPixels[trgIndex] setColor(trgPixel,color) trgIndex = trgIndex + 1 # Twice trgPixel = trgPixels[trgIndex] setColor(trgPixel,color) trgIndex = trgIndex + 1 show(canvas) return canvas
![Page 95: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/95.jpg)
Scaling up just the Facedef copyHorseFaceLarger(): # Set up the source and target pictures src=makePicture("horse.jpg") canvas = makeEmptyPicture(163*2,308*2) # Now, do the actual copying sourceX = 104 for targetX in range(0,163*2): sourceY = 114 for targetY in range(0,308*2): srcpx = getPixel(src,int(sourceX),int(sourceY)) color = getColor(srcpx) setColor(getPixel(canvas,targetX,targetY), color) sourceY = sourceY + 0.5 sourceX = sourceX + 0.5 show(canvas) return canvas
![Page 96: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/96.jpg)
Scaling the picture updef copyBarbsFaceLarger(): # Set up the source and target pictures barbf=getMediaPath("barbara.jpg") barb = makePicture(barbf) canvasf = getMediaPath("7inX95in.jpg") canvas = makePicture(canvasf) # Now, do the actual copying sourceX = 45 for targetX in range(100,100+((200-45)*2)): sourceY = 25 for targetY in range(100,100+((200-25)*2)): color = getColor(getPixel(barb,int(sourceX),int(sourceY))) setColor(getPixel(canvas,targetX,targetY), color) sourceY = sourceY + 0.5 sourceX = sourceX + 0.5 show(barb) show(canvas) return canvas
![Page 97: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/97.jpg)
Scaling up: How it worksSame basic setup as
copying and rotating:
![Page 98: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/98.jpg)
Scaling up: How it works 2But as we increment
by only 0.5, and we use the int() function, we end up taking every pixel twice.
Here, the blank pixel at (0,0) in the source gets copied twice onto the canvas.
![Page 99: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/99.jpg)
Scaling up: How it works 3Black pixels gets
copied once…
![Page 100: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/100.jpg)
Scaling up: How it works 4And twice…
![Page 101: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/101.jpg)
Scaling up: How it ends upWe end up in the
same place in the source, but twice as much in the target.
Notice the degradation: Gaps that weren't there
previously Curves would get “choppy”:
Pixelated
![Page 102: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/102.jpg)
What to do?How do we clear up the degradation of
scaling up?Variety of techniques, but mostly following
the same basic idea:Use the pixels around to figure out what color
a new pixel should be, then somehow (e.g., by averaging) compute the right color.
Different techniques look at different pixels and compute different averages in different ways.
![Page 103: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/103.jpg)
A simple Blurdef blur(source): target=duplicatePicture(source) for x in range(1, getWidth(source)-1): for y in range(1, getHeight(source)-1): top = getPixel(source,x,y-1) left = getPixel(source,x-1,y) bottom = getPixel(source,x,y+1) right = getPixel(source,x+1,y) center = getPixel(target,x,y) newRed=(getRed(top)+ getRed(left) + getRed(bottom) + getRed(right) + getRed(center))/5 newGreen=(getGreen(top) + getGreen(left) + getGreen(bottom)+getGreen(right)+getGreen(center))/5 newBlue=(getBlue(top) + getBlue(left) + getBlue(bottom) + getBlue(right)+ getBlue(center))/5 setColor(center, makeColor(newRed, newGreen, newBlue))
![Page 104: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/104.jpg)
A different blurdef blur(pic,size): for pixel in getPixels(pic): currentX = getX(pixel) currentY = getY(pixel) r = 0 g = 0 b = 0 count = 0 for x in range(currentX - size,currentX + size): for y in range(currentY - size, currentY + size): if(x<0) or (y<0) or (x >= getWidth(pic)) or (y
>=getHeight(pic)): pass # Skip if we go off the edge else: r = r + getRed(getPixel(pic,x,y)) g = g + getGreen(getPixel(pic,x,y)) b = b + getBlue(getPixel(pic,x,y)) count = count + 1 newColor = makeColor(r/count,g/count,b/count) setColor(pixel,newColor)
We'll see pass and else later, but you can probably get a sense here of what's going on.
![Page 105: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/105.jpg)
Blurring out the pixelation
![Page 106: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/106.jpg)
Average from four sides, to compute new color
![Page 107: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/107.jpg)
Things to try:Can you come up with general copy, rotate,
copy, and scale functions?Take input pictures and parametersReturn the canvas the correct transformation
appliedAlso think about generalizing the
transformations:Scaling up and down by non-integer amountsRotating by something other than 90 degree
increments
![Page 108: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/108.jpg)
Blending picturesHow do we get part of one picture and part of
another to blur together, so that we see some of each?It's about making one a bit “transparent.”Video cards sometimes support this transparency
in hardware, called an alpha level to each pixel.We do it as a weighted sum
If it's 50-50, we take 50% of red of picture1's pixels + 50% of red of picture2's pixels, and so on for green and blue, across all overlapping pixels.
![Page 109: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/109.jpg)
Example blended picture
Blended here
![Page 110: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/110.jpg)
Blending code (1 of 3)def blendPictures(): barb = makePicture(getMediaPath("barbara.jpg")) katie = makePicture(getMediaPath("Katie-smaller.jpg")) canvas = makePicture(getMediaPath("640x480.jpg")) #Copy first 150 columns of Barb sourceX=0 for targetX in range(0,150): sourceY=0 for targetY in range(0,getHeight(barb)): color = getColor(getPixel(barb,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY),color) sourceY = sourceY + 1 sourceX = sourceX + 1
Straightforward copy of 150 column's of Barb's picture
![Page 111: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/111.jpg)
Blending code (2 of 3) #Now, grab the rest of Barb and part of Katie # at 50% Barb and 50% Katie overlap = getWidth(barb)-150 sourceX=0 for targetX in range(150,getWidth(barb)): sourceY=0 for targetY in range(0,getHeight(katie)): bPixel = getPixel(barb,sourceX+150,sourceY) kPixel = getPixel(katie,sourceX,sourceY) newRed= 0.50*getRed(bPixel)
+0.50*getRed(kPixel) newGreen=0.50*getGreen(bPixel)
+0.50*getGreen(kPixel) newBlue = 0.50*getBlue(bPixel)
+0.50*getBlue(kPixel) color = makeColor(newRed,newGreen,newBlue) setColor(getPixel(canvas,targetX,targetY),color) sourceY = sourceY + 1 sourceX = sourceX + 1
Here's the trick. For each pixel, grab 50% of each red, green and blue
![Page 112: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/112.jpg)
Blending code (3 of 3) # Last columns of Katie sourceX=overlap for targetX in
range(150+overlap,150+getWidth(katie)): sourceY=0 for targetY in range(0,getHeight(katie)): color = getColor(getPixel(katie,sourceX,sourceY)) setColor(getPixel(canvas,targetX,targetY),color) sourceY = sourceY + 1 sourceX = sourceX + 1 show(canvas) return canvas
![Page 113: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/113.jpg)
Drawing lines on Carolina
def lineExample(): img = makePicture(pickAFile()) verticalLines(img) horizontalLines(img) show(img) return img def horizontalLines(src): for x in range(0,getHeight(src),5): for y in range(0,getWidth(src)):
setColor(getPixel(src,y,x),black) def verticalLines(src): for x in range(0,getWidth(src),5): for y in range(0,getHeight(src)):
setColor(getPixel(src,x,y),black) We can use the color name “black” – it's pre-defined for us.
![Page 114: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/114.jpg)
Yes, some colors are already definedColors defined for you already: black, white,
blue, red, green, gray, lightGray, darkGray, yellow, orange, pink, magenta, and cyan
![Page 115: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/115.jpg)
That's tediousThat's slow and tedious to set every pixel you
want to make lines and text, etc.What you really want to do is to think in
terms of your desired effect (think about “requirements” and “design”)
![Page 116: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/116.jpg)
New functionsaddText(pict,x,y,string) puts the string
starting at position (x,y) in the pictureaddLine(picture,x1,y1,x2,y2) draws a line
from position (x1,y1) to (x2,y2)addRect(pict,x1,y1,w,h) draws a black
rectangle (unfilled) with the upper left hand corner of (x1,y1) and a width of w and height of h
addRectFilled(pict,x1,y1,w,h,color) draws a rectangle filled with the color of your choice with the upper left hand corner of (x1,y1) and a width of w and height of h
![Page 117: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/117.jpg)
The mysterious red box on the beachdef addABox(): beach = makePicture(getMediaPath("beach-
smaller.jpg")) addRectFilled(beach,150,150,50,50,red) show(beach) return beach
![Page 118: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/118.jpg)
Example picturedef littlepicture(): canvas=makePicture(getMediaPath("640x480.jpg")) addText(canvas,10,50,"This is not a picture") addLine(canvas,10,20,300,50) addRectFilled(canvas,0,200,300,500,yellow) addRect(canvas,10,210,290,490) return canvas
![Page 119: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/119.jpg)
A thought experimentLook at that previous page: Which has a
fewer number of bytes?The program that drew the pictureThe pixels in the picture itself.
It's a no-brainerThe program is less than 100 characters (100
bytes)The picture is stored on disk at about 15,000
bytes
![Page 120: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/120.jpg)
Vector-based vs. Bitmap Graphical representationsVector-based graphical representations are
basically executable programs that generate the picture on demand.Postscript, Flash, and AutoCAD use vector-
based representationsBitmap graphical representations (like JPEG,
BMP, GIF) store individual pixels or representations of those pixels.JPEG and GIF are actually compressed
representations
![Page 121: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/121.jpg)
Vector-based representations can be smallerVector-based representations can be much
smaller than bit-mapped representationsSmaller means faster transmission (Flash and
Postscript)If you want all the detail of a complex picture,
no, it's not.
![Page 122: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/122.jpg)
But vector-based has more value than that
Imagine that you're editing a picture with lines on it. If you edit a bitmap image and extend a line, it's just more bits.
There's no way to really realize that you've extended or shrunk the line.
If you edit a vector-based image, it's possible to just change the specification Change the numbers saying where the line is Then it really is the same line
That's important when the picture drives the creation of the product, like in automatic cutting machines
![Page 123: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/123.jpg)
How are images compressed?Sometimes lossless using techniques like run
length encoding (RLE)Instead of this:
B B Y Y Y Y Y Y Y Y Y B BWe could say “9 Y's” like this:
B B 9 Y B BLossy compression (like JPEG and GIF) loses detail, some
of which is invisible to the eye.
![Page 124: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/124.jpg)
When changing the picture means changing a program…In a vector-based drawing package, changing
the drawing is changing a program.How could we reach in and change the actual
program?We can using string manipulation
The program is just a string of charactersWe want to manipulate those characters, in
order to manipulate the program
![Page 125: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/125.jpg)
Example programmed graphicIf I did this right, we
perceive the left half as lighter than the right half
In reality, the end quarters are actually the same colors.
![Page 126: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/126.jpg)
Building a programmed graphicdef greyEffect(): file = getMediaPath("640x480.jpg") pic = makePicture(file) # First, 100 columns of 100-grey grey = makeColor(100,100,100) for x in range(1,100): for y in range(1,100): setColor(getPixel(pic,x,y),grey) # Second, 100 columns of increasing greyness greyLevel = 100 for x in range(100,200): grey = makeColor(greyLevel, greyLevel, greyLevel) for y in range(1,100): setColor(getPixel(pic,x,y),grey) greyLevel = greyLevel + 1
# Third, 100 colums of increasing greyness, from 0 greyLevel = 0 for x in range(200,300): grey = makeColor(greyLevel, greyLevel, greyLevel) for y in range(1,100): setColor(getPixel(pic,x,y),grey) greyLevel = greyLevel + 1 # Finally, 100 columns of 100-grey grey = makeColor(100,100,100) for x in range(300,400): for y in range(1,100): setColor(getPixel(pic,x,y),grey) return pic
![Page 127: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/127.jpg)
Another Programmed Graphicdef coolpic():
canvas=makePicture(getMediaPath("640x480.jpg"))
for index in range(25,1,-1): color = makeColor(index*10,index*5,index) addRectFilled(canvas,0,0,index*10,index*10,color) show(canvas) return canvas
![Page 128: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/128.jpg)
And anotherdef coolpic2(): canvas=makePicture(getMediaPath("640x480.jpg")) for index in range(25,1,-1): addRect(canvas,index,index,index*3,index*4)
addRect(canvas,100+index*4,100+index*3,index*8,index*10) show(canvas) return canvas
![Page 129: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/129.jpg)
Why do we write programs?Could we do this in Photoshop? Maybe
I'm sure that you can, but you need to know how.
Could I teach you to do this in Photoshop? MaybeMight take a lot of demonstration
But this program is an exact definition of the process of generating this pictureIt works for anyone who can run the program,
without knowing Photoshop
![Page 130: Chapter 6: Modifying Pixels by Position](https://reader036.vdocuments.mx/reader036/viewer/2022062317/5a4d1afc7f8b9ab0599845cd/html5/thumbnails/130.jpg)
We write programs to encapsulate and communicate processIf you can do it by hand, do it.If you need to teach someone else to do it,
consider a program.If you need to explain to lots of people how to
do it, definitely use a program.If you want lots of people to do it without
having to teach them something first, definitely use a program.