Student: Prof, my friend took a different CS course and they said we’re representing images all wrong.
Prof: Oh? How so?
Student: The pictures in their class are all represented as arrays of arrays of colors. They call them pixels.
Prof: Ah, they are working with rasterized images!
Student: Huh?
Prof: We can have them, too! It’s a different way of thinking about a picture. Rather than having logical shapes placed on or next to each other, we think about the grid of pixels. Both are valid ways of thinking about an image. And our
Pict objects can go back and forth to the array representation. Every Pict has a render() method. Let’s check it out:Prof: They show up as the same image, but they have different internal representations. Note the
3x4 in the printed version of the Raster, which matches the size of the Rect it came from. We could create the same Raster by using its constructor:Student: Huh, interesting. What’s that
import line for, and why are we using Color.RED instead of "red"?Prof: The way
Raster is represented uses some of the built-in Java types for doing drawings. The Pict constructors like Rect and Circle have some conveniences for using string names, but once we get to Raster we will be talking more about colors as Java sees them. This is part of the java.awt library.Student: OK, I see. When it prints it’s saying
r, g, and b. What’s that about?Prof: Great question, it is called the RGB model of colors.
R for red, G for green, and B for blue. Combining different amounts of red, green, and blue can express a wide array of colors, and its one of the standard ways computers represent them. So a raster is an array of arrays of colors, where each color has these three components. Since we used Color.RED, that’s all red. You could create your own colors with different amounts! Here’s the same example with a nice mix of blue and green:Student: OK, I think I see. That’s a lot of typing to build a really small image, though, right?
Prof: Indeed! We will need a lot more infrastructure to build up interesting images from this. But there are also things we can do with
Raster that would be hard to do any other way.Practice
A Raster has methods width(), height(), and colorAt(x, y), where x counts across from the left and y counts down from the top, both starting at 0. Here is a small striped flag:
Color[][] stripes = {
{ Color.RED, Color.WHITE, Color.RED, Color.WHITE, Color.RED },
{ Color.RED, Color.WHITE, Color.RED, Color.WHITE, Color.RED }
};
Raster flag = new Raster(stripes);What does each expression produce?
flag.width()
flag.height()
flag.width() is the same as
flag.colorAt(3, 1)
flag.height()
flag.width() is the same as
flag.colorAt(3, 1)
Now go the other way, from a Pict to a Raster:
Raster dot = new Circle(5, "green").render();A circle is round, but a raster is always a rectangle of pixels, so some pixels are inside the circle and some are not. Pixels outside the circle are transparent.
dot.width()
dot.height()
dot.colorAt(5, 5)
dot.colorAt(0, 0)
dot.colorAt(2, 7)
dot.colorAt(9, 9)
dot.height()
dot.colorAt(5, 5)
dot.colorAt(0, 0)
dot.colorAt(2, 7)
dot.colorAt(9, 9)