Copying: How it works Here's the initial setup:. Copying: How it works 2 After incrementing the sourceY and targetY once (whether in the for or via expression):

Slides:



Advertisements
Similar presentations
Creative Computing. \\ aims By the end of the session you will be able to: 1.Explain the difference between various image file formats 2.Load in and display.
Advertisements

A Media Computation Cookbook Manipulating Images and Sounds for Use in Alice Part 1: Image Manipulations Part 2: Advanced Image Manipulations, e.g., changing.
RAPTOR Syntax and Semantics By Lt Col Schorsch
PHY-102 SAPIntroductory GraphicsSlide 1 Introductory Graphics In this section we will learn how about how to draw graphics on the screen in Java:  Drawing.
CS2984: Introduction to Media Computation Drawing directly on images.
The Binary Numbering Systems
Sound, Part 2 Using range to manipulate samples by index number.
1 CS 177 Week 6 Recitation Slides Scaling Drawing on images Vector-based Vs. Bitmap graphical representation.
Graphics and Still Images John H. Krantz Hanover College.
Some Utility Functions If you know the name of the file, searching for it with pickAFile() feels tedious You can set and get a media folder (path) for.
Introduction to Computer Graphics
Graphical images Bit-mapped (or raster-based) image: Matrix describing the individual dots that are the smallest elements (pixels) of resolution on a computer.
Georgia Institute of Technology Two-Dimensional Arrays and Nested Loops – part 6 Barb Ericson Georgia Institute of Technology August 2005.
TOPIC 9 MODIFYING PIXELS IN A MATRIX: COPYING, CROPPING 1 Notes adapted from Introduction to Computing and Programming with Java: A Multimedia Approach.
CSE 8A Lecture 8 Reading for next class: None Prepare for In-term exam 2 PSA4: Collage and Picture Flip, DON’T WAIT (it’s longer than the previous PSAs)
Copying and Transforming Pictures. First, finding the min or max… Next homework asks you to write a function to find the darkest and lightest shade of.
NestedLoops-part31 Nested Loops – part 3 Barb Ericson Georgia Institute of Technology Nov 2009.
Introduction to Computing and Programming in Python: A Multimedia Approach Chapter 5: Advanced Picture Techniques.
Digital Images The digital representation of visual information.
UWCSE BRIDGE Workshop Aug. 31 – Sept. 3, 2009 Hal Perkins Computer Science & Engineering University of Washington
Lecture 4 - Introduction to Computer Graphics
Color Correct and Remove Keystoning A minimalist approach to photographing your art By Paul Marley.
CS1315: Introduction to Media Computation Picture encoding and manipulation.
CS1315: Introduction to Media Computation Picture encoding and manipulation.
Chapter 6: Modifying Pixels by Position. Chapter Learning Goals.
02-RangesInPictures1 Barb Ericson Georgia Institute of Technology Oct 2010 Working with ranges in pictures.
CS2984: Introduction to Media Computation Using Loops for Pictures Conditionals Copying images.
Image Representation. Objectives  Bitmaps: resolution, colour depth and simple bitmap file calculations.  Vector graphics: drawing list – objects and.
Lecture 4 Pixels, Images and Image Files 1. In this Lecture, you will learn the following concepts: Image files (in particular, the BMP file format) How.
Computer Graphics Bitmaps & Sprites CO2409 Computer Graphics Week 3.
Pixels, Images and Image Files 1 By Dr. HANY ELSALAMONY.
Digital Multimedia, 2nd edition Nigel Chapman & Jenny Chapman Chapter 3 This presentation © 2004, MacAvon Media Productions Introduction to Computer Graphics.
CS1315: Introduction to Media Computation Picture encoding and manipulation.
Program Design and Debugging. How do programmers start? How do you get started with a program? “Programming is all about debugging a blank piece of paper.”
1 CS 177 Week 5 Recitation Slides Mirroring and copying images, Using for Loop, if statement, and range.
CS 101: Introduction to Computing Rotating and Blurring Developed by Mark Guzdial, Georgia Institute of Technology, 2003–2004; modified by Robert H. Sloan,
Chapter 4: Modifying Pixels in a Range (partial slide deck)
Introduction to Computing and Programming in Python: A Multimedia Approach Chapter 4: Modifying Pixels in a Range.
CS1315: Introduction to Media Computation How to design and debug a program: Top-down, bottom-up, and debugging. Using background subtraction and chromakey.
Graphics An image is made up of tiny dots called pixels (“picture elements”) The resolution determines the.
Digital Media Dr. Jim Rowan ITEC So far… We have compared bitmapped graphics and vector graphics We have discussed bitmapped images, some file formats.
NestedLoops-part41 Nested Loops – part 4 Barb Ericson Georgia Institute of Technology Nov 2009.
Introduction to Computing and Programming in Python: A Multimedia Approach Chapter 5: Advanced Picture Techniques.
Chapter 5: Advanced Picture Techniques. Chapter Objectives.
Image File Formats. What is an Image File Format? Image file formats are standard way of organizing and storing of image files. Image files are composed.
Yet Another Version. More Careful Edge Detection def lineDetect(filename): orig = makePicture(filename) makeBw = makePicture(filename) for x in range(0,getWidth(orig)-1):
A Media Computation Cookbook Manipulating Images and Sounds for Use in Alice Part 1: Image Manipulations Part 2: Advanced Image Manipulations, e.g., changing.
NestedLoops-part21 Nested Loops – part 2 Barb Ericson Georgia Institute of Technology Nov 2009.
Chapter 6: Modifying Pixels by Position
CSC 112Introduction to Media Computation 1 Rotating Images.
CS1315: Introduction to Media Computation Transforming pictures by index number.
Introduction to Computing and Programming in Python: A Multimedia Approach Chapter 4: Modifying Pixels in a Range.
Graphics and Image Data Representations 1. Q1 How images are represented in a computer system? 2.
CompSci 4 Java 4 Apr 14, 2009 Prof. Susan Rodger.
Chapter 5: Picture Techniques with Selection
Pixels, Colors and Shapes
Topic 9 Modifying Pixels in a Matrix: Copying, Cropping
Binary Representation in Audio and Images
Computer Science Higher
Picture Functions ppp =makePicture(pickAFile())
Basic Graphics Drawing Shapes 1.
Introduction to Computer Graphics
Working with ranges in pictures
Gray Scale picture def pixBW(pixel): # given a pixel, change to BW
Chapter 4: Modifying Pixels in a Range
Two-Dimensional Arrays and Nested Loops – part 6
CSC1401 Viewing a picture as a 2D image - 2
Two-Dimensional Arrays and Nested Loops – part 6
CS1315: Introduction to Media Computation
Chapter 4: Modifying Pixels in a Range
Presentation transcript:

Copying: How it works Here's the initial setup:

Copying: How it works 2 After incrementing the sourceY and targetY once (whether in the for or via expression):

Copying: How it works 3 After yet another increment of sourceY and targetY: When we finish that column, we increment sourceX and targetX, and start on the next column.

Copying: How it looks at the end Eventually, we copy every pixel

Making a collage Could 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!

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 (4ed edition)

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

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

Make sure you have this Typed IN to Work From: Copy Any Pic

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

>>> c = makePicture("caterpillar.jpg") >>> copyPicDifferent(c,c1,10,10) >>> explore(c1) >>> copyAnyPic(c,c1,10,10) >>> explore(c1)

Transformation = Small changes in copying Making relatively small changes in this basic copying program can make a variety of transformations. Change the targetX and targetY, and you copy wherever you want Cropping: Change the sourceX and sourceY range, and you copy only part of the program. Rotating: Swap targetX and targetY, and you end up copying sideways Scaling: Change the increment on sourceX and sourceY, and you either grow or shrink the image.

Copying face to small canvas def 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

Changing while copying def 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

Copying vs. Referencing >>> a = 100 >>> b = a >>> print a,b 100 >>> b = 200 >>> print a,b >>> a = 300 >>> print a,b

Referencing works differently >>> pictureBarb = makePicture("barbara.jpg") >>> pixel1 = getPixelAt(pictureBarb,0,0) >>> print pixel1 Pixel red=168 green=131 blue=105 >>> anotherpixel = pixel1 >>> print anotherpixel Pixel red=168 green=131 blue=105 >>> setColor(pixel1,black) >>> print pixel1 Pixel red=0 green=0 blue=0 >>> print anotherpixel Pixel red=0 green=0 blue=0

Making a collage Could 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!

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 (2ed edition)

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

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

Rotating the copy def 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

Rotating: How it works We increment the same, but we use targetX for the Y coordinate and targetY for the X coordinate

Rotate: How it ends Same amount of increment, even same values in the variables, but a different result.

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

Scaling Scaling a picture (smaller or larger) has to do with sampling the source picture differently When we just copy, we sample every pixel If we want a smaller copy, we skip some pixels We sample fewer pixels If we want a larger copy, we duplicate some pixels We over-sample some pixels

Scaling the horse face down def 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

Scaling the picture down def 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

Scaling Up: Growing the picture To 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

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

Scaling up just the Face def 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 sourceX = sourceX show(canvas) return canvas

Scaling the picture up def 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 sourceX = sourceX show(barb) show(canvas) return canvas

Scaling up: How it works Same basic setup as copying and rotating:

Scaling up: How it works 2 But 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.

Scaling up: How it works 3 Black pixels gets copied once…

Scaling up: How it works 4 And twice…

Scaling up: How it ends up We 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

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.

A simple Blur def 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))

A different blur def 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 = 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.

Blurring out the pixelation

Average from four sides, to compute new color

Things to try: Can you come up with general copy, rotate, copy, and scale functions? Take input pictures and parameters Return the canvas the correct transformation applied Also think about generalizing the transformations: Scaling up and down by non-integer amounts Rotating by something other than 90 degree increments

Blending pictures How 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.

Example blended picture Blended here

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

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

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

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.

Yes, some colors are already defined Colors defined for you already: black, white, blue, red, green, gray, lightGray, darkGray, yellow, orange, pink, magenta, and cyan

That's tedious That'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”)

New functions addText(pict,x,y,string) puts the string starting at position (x,y) in the picture addLine(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

The mysterious red box on the beach def addABox(): beach = makePicture(getMediaPath("beach-smaller.jpg")) addRectFilled(beach,150,150,50,50,red) show(beach) return beach

Example picture def 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

A thought experiment Look at that previous page: Which has a fewer number of bytes? The program that drew the picture The pixels in the picture itself. It's a no-brainer The program is less than 100 characters (100 bytes) The picture is stored on disk at about 15,000 bytes

Vector-based vs. Bitmap Graphical representations Vector-based graphical representations are basically executable programs that generate the picture on demand. Postscript, Flash, and AutoCAD use vector-based representations Bitmap graphical representations (like JPEG, BMP, GIF) store individual pixels or representations of those pixels. JPEG and GIF are actually compressed representations

Vector-based representations can be smaller Vector-based representations can be much smaller than bit-mapped representations Smaller means faster transmission (Flash and Postscript) If you want all the detail of a complex picture, no, it's not.

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

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 B We could say “9 Y's” like this: B B 9 Y B B Lossy compression (like JPEG and GIF) loses detail, some of which is invisible to the eye.

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 characters We want to manipulate those characters, in order to manipulate the program

Example programmed graphic If 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.

Building a programmed graphic def 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

Another Programmed Graphic def 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

And another def 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

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? Maybe Might take a lot of demonstration But this program is an exact definition of the process of generating this picture It works for anyone who can run the program, without knowing Photoshop

We write programs to encapsulate and communicate process If 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.