☰ Contents Nested and 2D Structures

Negatives

Prof: Now that we have this loop idea, we can do interesting things like mess with the colors. Have you ever heard of a negative of an image?
Student: Maybe? Like where the colors are all weird?
Prof: Right. The negative is the result of “inverting” all the colors. So if r was 50 in the original, make it 205 in the negative. The arithmetic is 255 - c for each color channel c. This turns, say, purple (red and blue, no green) into green, just like on a color wheel.
Student: Let’s see what it looks like?
Prof: For now, I’m going to set this up to return a new Raster to show a builder style for these (we could also use a updater style).
Student: I see, so it has its own definition of “inverting” and it applies that to every color. And it returns a new Raster?
Prof: Right, the original is unchanged. And I just wrote small tests; we can scale it up to larger images:
Student: Neat!
Prof: In general we call these “image filters” – can you think of any others?
Student: Maybe like making it black and white, or just having one color?
Prof: Yup. And there are lots of others we could try if we wanted to get deep into graphics, like blurring or removing parts of an image. For now we’ll keep it with the kinds of examples you’ve suggested. We could also rotate, crop, flip, and so on.
Student: Cool!

Practice

Using negate and negative from above, what does each expression produce?
negate(new Color(50, 100, 200))
negate(Color.WHITE)
negative(negative(salk)).equals(salk)
negative is a builder: it makes a new Raster and leaves the old one alone. Raster also has an updater method, setColorAt(x, y, color), which changes one pixel in place. Fill in the body of the inner loop so that negateInPlace turns r itself into its negative.
import java.awt.Color;
Color negate(Color c) {
return new Color(255 - c.getRed(), 255 - c.getGreen(), 255 - c.getBlue());
}
void negateInPlace(Raster raster) {
for(int row = 0; row < raster.height(); row += 1) {
for(int col = 0; col < raster.width(); col += 1) {

}
}
}
Color[][] colors = {
{ Color.RED, Color.WHITE },
{ Color.BLACK, new Color(50, 100, 200) }
};
Raster r = new Raster(colors);
After negateInPlace(r) runs on the r above, what is colors[0][0]?
  1. Color.RED, still: new Raster(colors) copied the colors into the raster’s own grid, so setColorAt changes that copy, not colors.
  2. The negative of red, java.awt.Color[r=0,g=255,b=255].
    That would be true if the raster kept colors itself, like the two Menus that shared one array. The Raster constructor makes its own copy instead.
  3. null
    negateInPlace has a void result and works through raster; it never sets anything to null.