390 likes | 527 Views
Programming for Geographical Information Analysis: Core Skills. Lecture 9:Core Packages: Images and Drawing. This lecture. Colour Images Drawing IDEs. Background. You can change the background colour of any container with: someObject .setBackground ( someColor );
E N D
Programming for Geographical Information Analysis:Core Skills Lecture 9:Core Packages: Images and Drawing
This lecture Colour Images Drawing IDEs
Background You can change the background colour of any container with: someObject.setBackground(someColor); Here someColor is a object of type java.awt.Color. Note the US spelling.
Color Comes with static types you can use: setBackground(Color.RED); Or you can set them up with RGB (red, green, blue) values between 0 and 255: Color red = new Color(255,0,0); setBackground(red); There’s actually also a transparency (alpha: RGBA) level you can set, but anything other than 0 (clear) and 255 (opaque) is poorly supported. Color red = new Color(255,0,0,255); There are also options for using hue, saturation, brightness (HSB) instead.
Common colours new Color (255,0,0) Red new Color (0,255,0) Green new Color (0,0,255) Blue new Color (0,0,0) Black new Color (127,127,127) Medium grey new Color (255,255,255) White Note that whenever the values are the same, you get greyscale.
Color methods If we get a Color object, e.g. from an image, we can find out the RGB values thus: int r = ourColor.getRed(); int g = ourColor.getGreen(); int b = ourColor.getBlue();
This lecture Colour Images Drawing IDEs
Images Images are stored in java.awt.Image objects. Read them from files using a javax.imageio.ImageIO. Make them yourself.
Images Main way of making them from scratch is with a java.awt.image.MemoryImageSourceobject. A MemoryImageSourceobject takes in an int[] array and turns it into an image in memory: MemoryImageSource(int width, int height, int[] pixel, intarrayStart, intscanLineWidth)
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 All this space is 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 00000001 11111111 01111111 11111111 = compressed weirdness
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: Colorcolor = new Color(r,g,b); intpackedInt = color.getRGB(); You can also make a Color object using a packed int: Colorcolor = 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. MemoryImageSourcememImage = 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, intstartArray, intscanLineWidth) 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.
This lecture Colour Images Drawing IDEs
Drawing on components All containers have a ‘graphics context’ which is encapsulated in a ‘Graphics’ class object. We can get the Graphics object and use its methods to draw… Frame f = new Frame(); Graphics g = f.getGraphics(); g.drawline(0,0,300,200); // x1, y1, x2, y2 g.dispose(); or, if we’re in the frame class... Graphics g = getGraphics(); g.drawline(0,0,300,200); g.dispose(); All graphics are relative to the upper left corner (0, 0). If drawings stray outside the Component’s size, they’re clipped automatically (i.e. they’re stopped at the edges).
Displaying an Image We can then use a Graphics object’s drawImage method to draw the image to the screen. drawImage(Image im, int left, int top, ImageObserverimob); g = frame.getGraphics(); g.drawImage(image,0,0,panel); All components implement ImageObserver. This interface has one method imageUpdate, which returns whether an image has finished loading.
Vector drawing methods drawLine(intstartx, intstarty, intendX, intendY) drawOval(inttopLeftX, inttopLeftY, width, height) drawRect(inttopLeftX,topLeftY,lowRightX,lowRightY) drawPolygon(int[] xs, int[] ys, intnumberOfPoints) drawPolygon closes polygons automatically. drawString(String str, int x, int y) To set the font you need a java.awt.Font class object. To get the line height etc. so you know where to start the next line you need a java.awt.FontMetrics class object.
Drawing on Frames Note that setSize() sets the total size, so you lose some space under the menu, side borders etc. You can find these “insets”. The following wouldn’t be unusual: Insets insets = getInsets(); setSize(300 + insets.left + insets.right, 300 + insets.top + insets.bottom); Or: g.drawString(“Top left text", getInsets().left, getFontMetrics(getFont()).getHeight() + getInsets().top ); This gets the default line height – drawString draws from y = bottom of the line.
Colour revisited Note: the Graphics object has a set colour encapsulated in a java.awt.Color object – all lines are drawn in this. Background set in Components not their Graphics objects: setBackground(Color colorObject) Graphics setXORMode(Color) - swaps present colour for Color if the background drawn over is the present colour.
Repaint The JVM calls components’ repaint() method when it feels like it (when maximized, uncovered). Repaint calls two methods: update() : ~ paints the background. paint(Graphics g) : ~ paints the foreground. If we don’t overwrite paint, each repaint the component will lose any graphics we’ve added as it repaints the default look. Even if you overwrite paint, call repaint() so update() runs.
Example: Frame with constant text Note that a Graphics object is passed in for you. import java.awt.*; public class TitlePanel extends Frame { public void paint (Graphics g) { g.drawString(“Hello World", 100, 100); } }
This lecture Colour Images Drawing IDEs
Tooling Up When you do real programming, it’s unlikely you’ll do it with Notepad++ and the command line compiler. You’ll probably use an Integrated Development Environment (IDE). These make your life easier. They take a little time to learn to use, but are worth the investment.
What do IDEs do? Usually have Syntax colouring (e.g. will colour keywords, strings, method names etc.) and line numbers, like Notepad++. Push-button formatting. Usually have one-push compiling and running. Usually have run-time debugging – stops when your code breaks, shows you where, and tells you the problem. Usually have a facility for stepping through code one line at a time, and watching how variables change. Some will highlight errors as you type. Often have “auto-complete” drop down lists – you type an Object’s name, and they give drop-down lists of the potential methods. Linking to other people’s code.
Other Functions Rapid Application Development (RAD) The software lets you draw user interfaces and writes the code for you. It may or may not then let you alter that code. Computer Aided Software Engineering (CASE) Tools CASE tools help structure the development process. They may contain facilities for generating UML, converting UML into code, and for seeing which classes are dependent on each other. UML – a way of drawing code – we’ll come back to this. Profilers/Refactoring tools Show unused code and speed bottlenecks. Allow quick altering of multiple files.
Other Functions Build scripting Software that reads scripts that compile your code into different forms. Version and repository control Links to online repositories that store code and maintain different versions you can roll-back to. Native compilation Compilation to executables that don’t rely on the JVM, or wrappers for code to install and run the JVM when appropriate.
Popular Java IDEs Free: Netbeans(Oracle) http://netbeans.org/ Eclipse (IBM) http://www.eclipse.org/ JDeveloper(Oracle; originally based on JBuilder; specifically for Enterprise development) http://www.oracle.com/technetwork/developer- tools/jdev/overview/index.html BlueJ(Kent Uni; Basic beginners IDE) http://www.bluej.org/ Commercial: IntelliJIDEA (JetBrains; there is a free version) http://www.jetbrains.com/idea/ JBuilder (Was Borland, now Embarcadero) http://www.embarcadero.co.uk/products/jbuilder
Netbeans Big advantage of being built by Oracle, therefore well tied to Java. Written in Java, so developers can use it as the foundation for other software and build plugins for it in Java.
Eclipse Lots of plugins for major pieces of software (e.g. ArcGIS).
Conclusions Find what best suits your practice. But have a go at both Netbeans and Eclipse so you can operate in both. Don’t forget the command line and Notepad++ for quick jobs / lowest common denominator backtrack and old skool retro fun.
Practical Images Next lecture Network communications