Computer Science 111, Fall 2006 - Lab #5 - October 5, 2006

The purpose of today's lab is to modify images and sounds using jython, via for loops, counting, and double indexing. Hopefully this will be fun.

Part 1. Boot into Linux, Log in, and Open a Terminal Window

Part 2. Making JarJar's middle green-less
change directories (cd) to Desktop/JES and open, with emacs, a file called lab5.py and type in:

# Acct: 111a
# Date: Oct 2, 2006

from media import *

def main():
        file  = "images/starWars4.jpg"
        picture = makePicture(file)
        show(picture)

        x = getWidth(picture)
        y = getHeight(picture)
        x_third = x/3
        y_third = y/3

        for i in range(x_third, 2*x_third):
                for j in range(y_third, 2*y_third):
                        pixel = getPixel(picture, i, j)
                        setGreen(pixel, 0)
        repaint(picture)
        writePictureTo(picture,"centerGreen.jpg")


If you do not have starWars4.jpg, do
getcopy starWars.jpg
mv starWars.jpg images/starWars.jpg
Recall that when we use the from media import * statement, we can use the media module's functions and objects without putting media. in front of each one. Exit from emacs and invoke the jython interpreter,
jes
>>> import Lab5
>>> lab5.main()
You should see JarJar's picture with no green in the center part:

Part 3. do some more image manipulation
In the same file, after the definition for main(), write another definition for a function called checker(). It will start like this (and you can copy and paste from the web page if you want to:

def checker():
        file  = "images/starWars4.jpg"
        picture = makePicture(file)
        show(picture)

        x = getWidth(picture)
        y = getHeight(picture)
        x_third = x/3    # one-third of the way across
        y_third = y/3    # one-third of the way down

	# i is the 
        for i in range(1,x+1):   
                for j in range(1, y+1):
                        pixel = getPixel(picture, i, j)
Still inside the inner for-loop, after getting the pixel, use an if-else statement to check the values of i, and j. Use setGreen() and setRed() to set either the red or the green value of pixel to 255 depending on the i,j values. Make a checkerboard like this:
I used one if-else statement, with another if-else statement inside each part. You may do this, or construct a long if-elif-...-elif-else statement. There are a number of ways to do it. Don't forget that you have the values x_third and y_third to work with.
To run this function just do what you usually do:
jes
>>> import lab5
>>> lab5.checker()

Part 4. making negatives
After the two function definitions above, write another definition for a function called negate(). It will start like this:

def negate():
        file = "images/starWars4.jpg"
        picture = makePicture(file)
        show(picture)
        for p in getPixels(picture):
In side the for loop, use the functions (from media.py) getBlue(), getRed(), and getGreen() to get the values for the Red, Blue, and Green components of the current pixel (remember lab3 and hw3?). Then use setRed(), setBlue(), and setGreen() to change the values to their negative value. Remember the min value is 0 and the max value is 255. If the red component is 0 (no red) then the negative would be 255. What if red is 5? The negative component would be 250.
Don't forget to repaint() your picture after the for loop. The result should look like this:

Part 5. changing sounds
After the other definitions in your file, type in this one (or copy and paste):

def merge():
        s1 = makeSound("sounds/yodalaff.wav")
        s2 = makeSound("sounds/blaster.wav")
        s3 = makeSound("sounds/starWars7.wav")
        index = 1

        for i in [s1,s2]:
                play(i)
                time.sleep(1.5)
        for num in range(3):
        #Copy s1
                for source in range(1, getLength(s1)):
                        val = getSampleValueAt(s1, source)
                        setSampleValueAt(s3, index,val)
                        index = index + 1
        #Copy s2
                for source in range(1, getLength(s2)):
                        val = getSampleValueAt(s2, source)
                        setSampleValueAt(s3, index,val)
                        index = index + 1
        play(s3)
This one first plays sounds s1 and s2 with a delay in between. Then it copies s1 then s2 three times into the beginning of s3. You should hear
yodalaff, blaster, yodalaff, blaster, yodalaff, blaster, rest of startrek
wav files are files that contain samples of a sound, every 0.0000889 seconds. The loop
for source in range(1, getLength(s1)):
is going through each individual sound sample (we know how many there are by using the getLength() function from media.py).
We have getSampleValueAt() and setSampleValueAt() to get and set the values of the individual samples.
We are also using a counter, stored in the variable named index, to keep track of where, in s3, to put the next sample.

Part 6. backwards blaster
Write a function definition, at the very end of your file lab5.py that starts this way:

def backwards():
        source = makeSound("sounds/blaster.wav")
        target = makeSound("sounds/blaster.wav")

        sourceIndex = getLength(source)
        for targetIndex in range(1, getLength(target) +1):
Inside the for loop, use functions getSampleValueAt() and setSampleValueAt() to get a sample from source, and store it in target, backwards. Then after the for loop, play source, then sleep for 1.5 seconds, then play target. We use the same file, "sounds/blaster.wav" to store the backwards blaster sound because it has exactly the same length - the same number of samples. It's kind of an easy way out. We will just replace every sample.
As an example, suppose length of source is 100 (it will be much larger). Sound sample number 1 from source should be stored in sample 100 in target. Sample 2 of source would be stored in sample 99 of target. Sample 3 of source would be stored in sample 98 of target. See the pattern?
Try to see how functions getSampleAt() and setSampleAt() are used in function merge(). Let me see your images before you leave. Thanks.

No HW this week. Have a nice break.