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)
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);
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]?Color.RED, still:new Raster(colors)copied the colors into the raster’s own grid, sosetColorAtchanges that copy, notcolors.- The negative of red,
java.awt.Color[r=0,g=255,b=255].That would be true if the raster keptcolorsitself, like the twoMenus that shared one array. TheRasterconstructor makes its own copy instead. nullnegateInPlacehas avoidresult and works throughraster; it never sets anything tonull.