Main way of making them from scratch is with a java.awt.image.MemoryImageSource object.
A MemoryImageSource object takes in an int[] array and turns it into an image in memory:
MemoryImageSource(int width, int height,
int[] pixel, int arrayStart, int scanLineWidth)
Making Images from data
We can create the pixel array ourselves. Pixels are made up of RGBA data. Again, each is 0 to 255.
The array is 1D as this is more efficient to dynamically process.
However, why is it just one array, not four?
With a bit of clever computing, we can squeeze all four RGBA values into one super-efficient array.
Packed ints
If we take four int values of up to 255:
00000000 00000000 00000000 00000001 = int 1
00000000 00000000 00000000 11111111 = int 255
00000000 00000000 00000000 01111111 = int 127
00000000 00000000 00000000 11111111 = int 255
The lefthand three bytes are wasted.
What we really need to do is this:
00000001 = int 1
00000000 11111111 = int 255
00000000 00000000 01111111 = int 127
00000000 00000000 00000000 11111111 = int 255
Joined together = compressed weirdness:
00000001 11111111 01111111 11111111
Making pixels: the hard way
So that's what we do.
You can do this very efficiently, using a series of 'bitwise' operators Java has for interacting with bits.
This is about as much fun as being continually kicked in the groin by a battery of mules.
Making pixels: the easy way
The Color class has methods to help change 0 -> 255 r, g, and b values into a packed int:
Color color = new Color(r,g,b);
int packedInt = color.getRGB();
You can also make a Color object using a compressed int:
Color color = new Color(packedInt);
int width = 16;
int height = 16;
int[] pixels = new int[width * height];
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
int value = 0;
Color pixel = new Color(value,value,value);
pixels[(h*width) + w] = pixel.getRGB();
}
}
int width = 16;
int height = 16;
int[] pixels = new int[width * height];
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
int value = (w * h > 255) ? 255 : w * h;
Color pixel = new Color(value,value,value);
pixels[(h*width) + w] = pixel.getRGB();
}
}
int width = 16;
int height = 16;
int[] pixels = new int[width * height];
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
int value = data[h][w];
Color pixel = new Color(value,value,value);
pixels[(h*width) + w] = pixel.getRGB();
}
}
Must re-range our data between 0 and 255 if below or above this.
Using MemoryImageSource
With the array of pixels we can build the java.awt.image.MemoryImageSource.
Encapsulates an image in the computer's memory.
Computers can have multiple output devices on which an image is displayed, so this doesn't represent a displayed image. To do this, we need to use a Component to convert it. They know about the display.
MemoryImageSource memImage =
new MemoryImageSource(16,16,pixels,0,16);
Panel panel = new Panel();
Image image = panel.createImage(memImage);
We'll see how to draw the image in a bit.
Sequence
Get an image array.
Create a MemoryImageSource object.
Create an Image object.
Making Images: PixelGrabbers
If we have an Image and we want the pixels, we can use a java.awt.image.PixelGrabber.
The PixelGrabber object does the exact opposite of MemoryImageSource.
PixelGrabber(Image img, int left, int top,
int width, int height, int [] pixels,
int startArray, int scanLineWidth)
int pixels[] = new int [100];
PixelGrabber pg =
new PixelGrabber(image,0,0, 16,16, pixels,0,16);
pg.grabPixels();
Putting it all together
We now have all the methods we need to build a small image processor:
First we get an image.
Then we use a pixelGrabber to pull the pixels into an array.
We then expand the pixels into their alpha, red, green and blue values.
We manipulate the values - for example filtering the data.
Putting it all together
We then recode the values into the int array.
We use a MemoryImageSource to put the pixels back in an Image.
We draw the image on the screen.
We then run to the pub and drink ourselves unconscious to celebrate being geek gods/goddesses unfettered by the mere trifling difficulties of everyday human beings.