Images and Drawing
[Part 10]
In this part we'll look at two visualisation elements: how to turn our data into images (plus how to extract data from images), and how to draw on the screen.
Further info:
Early colour computers only had 3 bits to represent colour
(or 4 bits, 3 plus a 'brightening' bit), resulting in an 8-colour scheme.
These are the colours matching the static final variables in the Color class:
Color.BLACK
Color.BLUE
Color.RED
Color.MAGENTA
Color.GREEN
Color.CYAN
Color.YELLOW
Color.WHITE
To which are added:
Color.ORANGE
Color.PINK
Color.DARK_GRAY
Color.GRAY
Color.LIGHT_GRAY
These early colour schemes allowed the development of superbly realistic computer graphics.
Quiz:
The correct set of values to generate a bright cyan is __________________.
255,0, 0
125,0, 0
0,125,125
0,255,255
Correct! The other colours are red, dark red, and medium cyan.
Further info:
One key piece of code when dealing with displaying data is the code to convert between a 2D array and a 1D array. Here it is. Can you work out how it works (try working through it with a 2 by 3 2D array and a length = 6 1D array on paper)?
for (int row = 0; row < data2D.length; row++) {
for (int col = 0; col < data2D[0].length; col++) {
data1D[(row * data2D[0].length) + col) = data2D[i][j];
}
}
Note two things about this. The first is that it only works on regular rectangular or square
arrays (why? and it isn't just because we use data2D[0].length
rather than
data2D[row].length
). The second is that it doesn't, as it is, produce a packed-int 1D array, just an
1D version of the original data.
Note also that in the slides we've talked about the image processing techniques that will teach you most about
how images work, but will still be relatively uncomplicated. There are more sophisticated ways of
treating images, and more complicated ways. If you are interested in displaying or processing
multiple images, you should check out bitshifting for fast packing (see, for a good explanation
bitshifting by Kushal Paudyal),
image streams and filters (chapter
from O'Reilly), and double buffering.
If you are interested in working with raster images containing multiple bands, you should
check out javax.imageio,
especially the ImageIO
class, and java.awt.image,
especially the BufferedImage
and Raster
classes.
Quiz:
Given the code below to convert 1D to 2D arrays:
for (int i = 0; i < data2D.length; i++) {
for (int j = 0; j < data2D[0].length; j++) {
data2D[i][j] = data1D[(j * data2D[0].length) + i);
}
}
What is wrong with the code is _____________.
- the assignment is the wrong way round
data2D[i][j]
data1D[(j * data2D[0].length) + i)
data2D[0].length
- nothing
Correct! The i and j are the wrong way round - to work out the location in a 1D array made by stretching out a 2D array, you
need to count how many rows you've had (i
) and multiple it by the row width (data2D[0].length
), then add on however many
cells you are across the current row (j
). This holds whether you are converting 1D to 2D, or 2D to 1D.
Further info:
Again, we've gone for describing the simplest and lowest-level options here. If you are interested in more complex drawing issues, including, for example, transformations, you should check out the java.awt.geom package and double buffering. If you are interested in mapping, you should check out the GeoTools library, which had its origins in our CCG group.
Quiz:
Given the code below:
int[] xs = {0, 10, 10, 0};
int[] ys = {0, 0, 10, 10};
java.awt.Polygon p = new java.awt.Polygon(xs,ys.xs.length);
if (p.contains(hitx, hity)) {
System.out.println("You've sunk my battleship!");
}
What is wrong with the code is _____________
- that the start and end points of the Polygon need to be the same.
- that it should be
Polygon
rather thanjava.awt.Polygon
. - that you can't represent squares using
java.awt.Polygon
. - nothing.
Correct! Polygons will close themselves, so they don't have to start and end at the same place.