In this section, we'll look how to use expressions to greatly expand what we can do in a loop. With expressions, we'll be able to write real image manipulation code, and in particular solve some puzzles based on images.
Expressions 1 + 1
We have seen code that "calls" a function where we pass in a value within the parenthesis, such as the value 42 passed in to the print function below.
Instead of a plain number like 42, an "expression" written in the code like 11 + 13 computes the value to use. For example you could write something like this:
print(11 + 31);
When that line runs, the computer first computes the expression 11 + 31, yielding 42. Then in effect it calls print(42), passing in the computed value. Anywhere in the code where we have used a fixed number like 0 or 255 of whatever, we can instead write an expression, letting the code compute a value when that line runs.
pixel.getRed() / pixel.getGreen() / pixel.getBlue()
We have not used them until now, but there are three pixel functions that get the red, green or blue value out of a pixel. These will be very handy to use in expressions.
pixel.getRed()-- retrieves the red value from a pixel
pixel.getGreen()-- retrieves the green value
pixel.getBlue()-- retrieves the blue value
Here is an example of getRed() - get the red number out of a pixel, store it in a variable named "red".
red = pixel.getRed();
Notice that calling, say,
pixel.getRed() has the pair of parenthesis () after it . The syntax requires that calling a function includes the parenthesis, even if there's nothing inside the parenthesis. A good example of the inflexible nature of computers.
Set/Get Pattern: combine pixel.setRed() and pixel.getRed()
- Suppose we want to double the red value of a pixel
- This is a more realistic sort of operation
- What is the sequence of events here?
// Doubles the pixel's red value red = pixel.getRed(); pixel.setRed(red * 2);
pixel.getRed() can be combined with
pixel.setRed(number) to operate on a pixel. For example, the above code snippet doubles the pixel's red value. The first line retrieves the red value from the pixel and stores that value in an variable named red. Say in this case that the red value is 50. The second line computes
red * 2 (100 in this case), and sets that value back into the pixel as its new red value. The net effect is to double the red value of the pixel from 50 to 100.
- The red variable is not necessary
- Reduce the whole get/set to one line
pixel.setRed(pixel.getRed() * 2);
- How does the line above work?
- Suppose that pixel red is 120
- Q: What does running the line above do to the pixel?
- 1. Evaluates the
pixel.getRed() * 2expression, ...
- 2. expression pixel.getRed() is 120
- 3. expression 120 * 2 is 240
- 4. calls
- Result is changing the pixel red from 120 to 240
- Whatever the red value, the line doubles it
pixel.getRed() * 2 is an expression, which is whatever the old red value was multiplied by 2. This expression is evaluated first, resulting a number such as 240. Then in effect pixel.setRed(240); is called. The setRed() etc. functions automatically limit the value set to the range 0..255. If setRed() is called with a value a greater than 255, it just uses 255, and likewise if a value less than 0 is passed in, it just uses the value 0.
Loops With Expressions - Set/Get Patterns
- Now can express relative color number changes
- e.g. double the red value (with set/get pattern):
pixel.setRed(pixel.getRed() * 2);
- e.g. halve the red value:
pixel.setRed(pixel.getRed() * 0.5);
- Bottom line, we'll use this pattern a lot:
pixel.setRed(pixel.getRed() * something);
Before we could only express ideas like "set the red value to 200". Now we can express what new value we want in terms of the old value, like "triple the red value", or "set the red value to 75% of what it was".
Image Expression Example 1
- Suppose we want to change the yellow flowers to look orange
- Set the green value to 75% of its original value (i.e. * 0.75)
- What is setGreen/getGreen combination to do this?
Image Expression Example 2 - You Try It
- Set red, green, and blue each to be * 0.75 of their original values, then try 0.5 and 0.25 (algorithm)
- What is the code to do this? (code)
- What is the effect on the image?
Image Expression Example 3 (optional)
- Try to improve the orange on the flowers
- Try modifying both red and green
- Change red to be 1.3 times its original value
- Change green to be 0.75 times its original value
- What is the code to do this?
5-10-20 Image Puzzles
- 5-10-20 Puzzles
- Image where red, green, and blue divided by 5, 10, or 20
- Scale them back up by * 5, * 10, * 20 to recover the original image
- Puzzle: don't know which number goes with which color
- Experiment to figure it out
- There are only 6 possibilities:
- 5 10 20, 5 20 10, 10 5 20, 10 20 5, 20 5 10, 20 10 5
- i.e. 5 first x 2, 10 first x 2, 20 first x 2
5-10-20 Banana Puzzle
- Yellow banana, background of dark red bricks
- Bits of dark green moss between the bricks
- Use code pattern:
pixel.setRed(pixel.getRed() * 5);
- Scale up all three colors, using factors 5, 10, 20 to fix the image
In the solution image, you will see some "banding" of the yellow of the banana. This is because the red and green channels were scaled down to a range as small as just 0, 1, 2, .. 12. With so few values, the image only represent a few different shades of yellow, and those are the bands we see if we look carefully at the banana. We will talk about "banding" more when we talk about digital media formats.