|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
DisclaimerPlease be advised that the code in this article is supplied as-is and without any guarantee, support or assurance of any kind. It has been tested and works well with JDK1.4 and JDK1.5. IntroductionEvery now and then, the need for small images for icons arises. More often than not, you don't have time to look for icons and drawing images for them with whatever graphics program is tedious at best, especially when writing the code is a more pressing matter. In the old days, for me it was the good old days of my Atari ST, you could design a simple icon by coloring pixels, but since this method also requires you load up some graphic software, it is slower than the oldest method to design icons. The first mouse pointer icons and other OS icons (even before Windows) were drawn using a bitmap matrix, and embedding the icon's data in your code has never been easier. This is what my BackgroundBefore I proceed to describe the code, I will explain how the bitmap matrix is defined. In the iimage displayed above, I use two patterns for the displayed icons: private final static String[] okPattern = {
"·······••",
"······••·",
"·····••··",
"•···••···",
"••·••····",
"·•••·····",
"··•······"
};
private final static String[] cancelPattern = {
"••·····••",
"·••···••·",
"··••·••··",
"···•••···",
"··••·••··",
"·••···••·",
"••·····••"
};
Whereas the additional data required to actually render the icons in color is given here: private final static char[] patternChars = {'•', '·'};
private Color[] okColours = {new Color(0, 100, 0), new Color(0, true)};
private Color[] cancelColours = {new Color(180, 0, 0), new Color(0, true)};
The Using the CodeThe private ImageIcon okIcon =
new ImageIcon(PatternColorFilter.createImage(this, true, okPattern,
patternChars, okColours));
private ImageIcon cancelIcon =
new ImageIcon(PatternColorFilter.createImage(this, true, cancelPattern,
patternChars, cancelColours));
The method signature for public static synchronized Image createImage
(java.awt.Component c, boolean transparent, String[] pattern,
char[] patternChars, Color[] patternColours);
The first parameter must be a Java AWT Component because of the way the image is created, all of which is explained in the next section. Explaining the CodeFollowing is the full source-code listing for the 01| import java.awt.*;
02| import java.awt.image.*;
03|
04| public class PatternColorFilter extends RGBImageFilter {
05| // Data members used by a specific PatternColorFilter instance..
06| private String[] pattern;
07| private char[] patternChars;
08| private Color[] patternColours;
09| private BufferedImage image;
10|
11| private PatternColorFilter(String[] pattern, char[] patternChars,
Color[] patternColours) {
12| // The constructor is private to prevent anyone from creating
// unwanted instances..
13| super();
14| // Set the private data members..
15| this.pattern = pattern;
16| this.patternChars = patternChars;
17| this.patternColours = patternColours;
18| canFilterIndexColorModel = true;
19| }
20|
21| public static synchronized Image createImage
(Component c, boolean transparent, String[] pattern,
char[] patternChars, Color[] patternColours) {
22| // Check the data arrays specified and return null if they are invalid..
23| if (patternChars == null || patternColours == null || pattern == null) {
24| // Invalid data arrays..
25| return null;
26| } else if (patternChars.length != patternColours.length) {
27| // Invalid data arrays..
28| return null;
29| }
30| // Obtain the width and height of the pattern array and verify it is even..
31| int width = 0;
32| int height = pattern.length;
33| for (int i = 0; i < pattern.length; i++) {
34| if (width == 0) {
35| width = pattern[i].length();
36| } else if (width != pattern[i].length()) {
37| // Uneven pattern array..
38| return null;
39| }
40| }
41| // Create a BufferedImage to work with..
42| BufferedImage image = new BufferedImage(width, height, transparent ?
BufferedImage.TYPE_INT_ARGB :
BufferedImage.TYPE_INT_RGB);
43| // Create an ImageProducer instance based on a PatternColorFilter instance..
44| FilteredImageSource fis =
new FilteredImageSource(image.getSource(),
new PatternColorFilter(pattern,
patternChars,
patternColours));
45| // Produce and return the image..
46| return c.createImage(fis);
47| }
48|
49| public int filterRGB(int x, int y, int rgb) {
50| // Is there a valid pattern to paint?
51| if (pattern != null) {
52| // Get the pattern's character..
53| char c = pattern[y].charAt(x);
54| // Loop through the pattern characters..
55| for (int i = 0; i < patternChars.length; i++) {
56| if (patternChars[i] == c) {
57| // Find the matching pixel RGB value and return it..
58| return patternColours[i].getRGB();
59| }
60| }
61| }
62| // Return the default RGB value specified by the method's invoker..
63| return rgb;
64| }
65| }
1. Extend RGBImageFilterJava's most basic Image Processing API has a class that performs all the boring work of filtering an image pixel-matrix for us. To quote the JavaDoc entry for RGBImageFilter:
By extending this class, we can take advantage of Java's Image Processing support and perform only the task absolutely necessary for solving the problem of creating an image on the fly from a pixel matrix (lines: 4, 49). 2. Construct Things WiselyEarly on, I had the notion that I would have to ensure my code is thread-safe and can run from various stages in a program's life-cycle. For this reason, each instance of 3. Divide and ConquerAs the 4. Under the HoodThe final method, In ConclusionI hope this article has shed some light on pixel manipulation of images and creation of images on the fly. Granted, this method of creating an image may not be the fastest or most efficient, especially not for very large images, however, the ease-of-use -- in my opinion -- is unparalleled by any other method employable by a busy programmer trying to meet a deadline. Once the code is stable and there is time to embellish your GUI with professionally created icons, go for it, but while things are just starting, and in the middle of a furious development cycle, the flexibility of the
|
||||||||||||||||||||||