Objectives:
Picture
picture = new Picture(FileChooser.pickAFile());
picture.show();
picture.explore();
The FileChooser class brings up a chooser
where you can browse for a picture file. You can use any of the
pictures in the mediaSources directory or use one of your own. The
show method simply displays your picture. The explore
method brings up a window that lets you examine the values at particular
locations within your picture.
Check
out the documentation for the Picture class. You will see that there
is a method getPixel(x,y) which will return the Pixel at a particular x an y
location. Check out the documentation for the Pixel class. You can see
that we can get the red, blue, and green values of a pixel and we can also
set the color of a pixel to another color. Try the following and check
that the pixel color has been changed. (You may want to use a color other
than black and different x and y values. You can check the
documentation of the Color class in the Java API to see what other built in
colors are available.)
import java.awt.Color;
picture.getPixel(10,100).setColor(Color.black);
picture.explore();
The import statement allows you to
access the Color class from the java.awt library.
If we
want to change a lot of the pixels in the same way, it would be extremely
tedious to have to write statements for each pixel. Instead, we need a
way of repeating the same statements for different objects. We will
now look at how to write methods that change some property of ALL the pixels in a
picture. Three types of loops are described in the chapter that allow
us to execute a group of statements many times.
The for-each loop is of the form
for (Type
variableName: arrayName){
// group of statements here...
}
The group of statements is performed for each element in the
array.
The following method which we can add to the Picture class decreases the red
value in each element of the array of pixels that make up the picture.
(Note in the code this.getPixels() we are invoking the method
getPixels on the picture for which the method is being used.)
public void
decreaseRedForEach(){
Pixel[] pixelArray = this.getPixels();
int value = 0;
// loop through all the pixels in the array
for (Pixel pixel : pixelArray){
// get the red value
value = pixel.getRed();
// decrease the red value by 50%
value = (int) (value * 0.5);
// set the red value of current pixel
to new value
pixel.setRed(value);
}
}
Add
that method to the Picture class. Now in the Interactions Pane, create a new picture
object and try this method on it. Show the new picture.
Another
type of loop is a while loop which is of the form
while (test){
// group of statements here...
}
The group of statements is performed as long as the test is
true.
The following method performs exactly the same as the previous one, only
with a while loop. Here, we have to use an index to specify which
pixel in the array we are using each time through the loop. Therefore
at the end of the loop we add 1 to the index so that we act upon the next
pixel in the next iteration of the loop.
public void
decreaseRedWhile(){
Pixel[] pixelArray = this.getPixels();
Pixel pixel = null;
int value = 0;
int index = 0;
// loop through all the pixels in the array
while (index < pixelArray.length){
// get the current pixel
pixel = pixelArray[index];
// get the red value
value = pixel.getRed();
// decrease the red value by 50%
value = (int) (value * 0.5);
// set the red value of current pixel
to new value
pixel.setRed(value);
// increment the index
index++;
}
}
Add this method to the Picture class and try it out.
A final
type of loop is a for loop which is of the form
for
(initialzation; test; change){
// group of statements here...
}
The for loop performs like a while loop except that the
initialization and the change of the index are built into the loop.
The following method performs exactly the same as the previous one, only
with a for loop.
public void
decreaseRedFor(){
Pixel[] pixelArray = this.getPixels();
Pixel pixel = null;
int value = 0;
// loop through all the pixels in the array
for (int index = 0; index < pixelArray.length; index++){
// get the current pixel
pixel = pixelArray[index];
// get the red value
value = pixel.getRed();
// decrease the red value by 50%
value = (int) (value * 0.5);
// set the red value of current pixel
to new value
pixel.setRed(value);
}
}
Add this method to the Picture class and try it out.
| Assignment: Write a Picture method keepBlue to keep just the blue color. This means you will set the green and red values to zero. |
| Assignment: Write a Picture method maximizeBlue which sets blue to its maximum value (255). Use a different type of loop than the one you used in the keepBlue method. |
| Assignment: Write a Picture method which morphs one picture into another. To morph one picture to another we will generate a sequence of intermediate images which will systematically appear more and more like the ending picture. Suppose that there are n intermediate images. We will compute the color values of red, green, and blue for each pixel of the kth intermediate image by computing a weighted average: color_value = start_color + ((end_color - start_color)/ n) * k Since this method does not operate on a single picture it will not be an object method but will be a class method. You can read about class methods on p41 of your text. We define a class method my using the keyword static. We will define the morph method as follows: /* Method to return a morphed intermediate image * @param start is the starting image * @param end is the ending image * @param n is the number of intermediate images * @param k is a position in the intermediate image * @return a the kth image in the intermediate image sequence */ public static Picture morph(Picture start, Picture end, int n, int k){ Picture result = new Picture(start.getWidth(), start.getHeight()); // set the color values of all the pixels in intermediate picture p return result; } Note that morph is creating a new Picture object of the same size as the starting image. It is also assumed that the ending image is the same size as well. (Later we will learn how to check that this condition holds). The new image is returned as output by the function at the end. You will need to get three arrays of pixels for the three images: start, end, and result. Use a while or for loop to iterate through all the pixels of the start image and use the same index in the end image to compute the pixels in the resulting image.
For each pixel, compute the weighted red, green,
and blue color values and set these values in your result pixel.
Picture.morph(start,end,4,1).show(); |