430 likes | 594 Views
Lecture 7. Graphics under AWT Graphics Attributes Shapes Clips Affine Transformations Strokes, Paints, Colors, Translucency RenderingHints, Anti-aliasing Importing and Exporting Graphics Double Buffering. Graphics under AWT.
E N D
Lecture 7 • Graphics under AWT • Graphics Attributes • Shapes • Clips • Affine Transformations • Strokes, Paints, Colors, Translucency • RenderingHints, Anti-aliasing • Importing and Exporting Graphics • Double Buffering
Graphics under AWT • The screen “real-estate” is all owned by somebody. You cannot draw on screen area owned by another. • Each component controls the way it, and to some extent its children, are drawn on screen. Parents draw first, then children draw, giving a layered effect of children “on top of” parents.
Making the component appear • Component.paint(Graphics g); contains the actual instructions for drawing the component. Override for custom look. • Component.update(Graphics g); first blanks the component by painting its background color, then calls paint. May override to reduce flicker. • Component.repaint(); calls update ASAP. update only called from a special thread.
The Graphics Object • All drawing is done through a Graphics object. This provides many drawing methods, which can be used to draw to many different locations (e.g. a screen region, a printer, an off-screen buffer). • An enhanced Graphics2D object was introduced along with Swing. It has some really excellent features.
Graphics2D Methods • Shape drawing/filling/erasing. • Text drawing • Image drawing • Hit detection (do 2 shapes overlap?)
Graphics2D Attributes • Color (foreground, background) • Line style (Stroke) • Fill style (Paint) • Composite (translucency effects) • AffineTransform (rotation, translation, scaling) • Font (for drawing text) • Clip Region (Shape): Graphics directives outside this region will be ignored. • RenderingHints: Antialiasing, speed, etc. For drawing lines, shapes and text Also for images
Pixels and Coordinates • The screen, which is an array of pixels, is thought of as part of an infinite plane. • Remember geometry? Every point in the plane can be described using 2 coordinates. By default, (0,0) indicates top-left corner, and (width,height) indicates bottom-right corner. • In Java, every pixel is a 1x1 square with 4 points as corners (pixels have area, they are not points).
Another pixel, with top-left corner (7,-2) -2 -1 ... -2 -1 0 1 2 3 4 5 6 7 8 9 0 1 The point (8.7, 3.4) Actual points have no height or width. 2 3 4 5 6 This pixel has corners (2,6), (3,6), (2,7) and (3,7). Pixels are the same as 1x1 rectangles. 7 8 9 10 11 12 The infinite plane
Shapes in the plane • A Shape is a class representing a subset of the plane. Every point in the plane is either inside or outside a particular Shape. • Shapes in Java are represented by a PathIterator, which describes the outline of the shape by breaking it up into simple curves.
Arc2D Ellipse2D GeneralPath RoundRectangle2D Shape Hierarchy QuadCurve2D Shape RectangularShape Line2D Polygon CubicCurve2D Rectangle2D, Rectangle
Gettin’ Shape • Use subclass from previous slide. GeneralPath is the most flexible. • Shape GlyphVector.getOutline(); Shape GlyphVector.getLogicalBounds(); Font.createGlyphVector(…); • Graphics.getClip(); • Stroke.createStrokedShape(Shape);
Usin’ Shape • boolean Shape.contains(Point); boolean Shape.contains(Rectangle); Rectangle Shape.getBounds2D(); boolean Shape.intersects(Rectangle); • Shape AffineTransform.createTransformedShape(Shape); • new Area(Shape); Area.add(Area); Area.intersect(Area); Area.subtract(Area); Area.isEmpty();
Showing off your Shape • Graphics2D.draw(Shape); This uses the Clip, Transform, Paint, Stroke, and Composite attributes to draw the outline of the shape. • Graphics2D.fill(Shape); This uses the Clip, Transform, Paint, and Composite to fill the interior of the shape. • Both methods make some assumptions about pixellation and anti-aliasing which may be controlled by Graphics2D.setRenderHints();
Screen: window onto a plane Screen rectangle The infinite graphics plane Only those pixels inside the “screen rectangle” are visible. Similarly, each Component has its own rectangle.
The clip rectangle Clip Rectangle The plane Each Component has its own Graphics object, which has its own “clip” rectangle, initially set to the size of the Component. You can draw anywhere on the plane, but only the clip rectangle will affect the screen.
Clip Rectangles • Actually, there are 3 clip rectangles: • The user clip, which you use to cut out the piece of the image you want to display. • The device clip, which is used to restrict your drawing to the allowed screen region. • The composite clip, which finally determines what is displayed. • Actually, these clips can be any Shape.
Example, System Clip • You load frogPic, a 200x200 image of a frog, and call g.drawImage(frogPic, 50,100); This is how it looks in the graphics plane. • Your component has size 150x250, This is how the component looks at its current size. It does not matter where your component is located on the screen. The system clip only allows part of the image.
Example, User Clip • Your BinocularsComponent already displays something like this. • Use g.setClip() to turn the user clip into the shape at left. Now whatever drawing instructions you give, graphics will only appear inside the white circles at top. If you draw this … this will display
Coordinates • Points in the plane are described by two coordinates. Locations are relative to the axes. But what describes where the axes are?
User space and device space • When you issue graphics commands, such as drawLine(x,y,width,height), or setClip(…), your inputs are treated as coordinates in user space (a coordinate space). • Before rendering to the screen, the instructions are converted to device space. • User space and device space have their own axes, and their own scales for each axis. These axes and scales can have any relation.
Affine Transformations • (Mathematics) Regardless of how two different coordinate systems are set up, there is an affine transformation which converts one to the other. • Affine transformations can be dilations, translations, rotations, shears, or any combination of these. • (demo)
Affine Transformation Uses • Makes your code simpler. • Translate origin to natural location. • Work in percentages—scale user coordinates. • Handle resized components with one line. • Some easy special effects • Rotated text and images • Shear (map rectangle to trapezoid)
Applying Affine Transforms Graphics2D.translate(); Graphics2D.rotate(); Graphics2D.scale(); Graphics2D.shear(); Graphics2D.transform(); Graphics2D.getTransform(); Graphics2D.setTransform(); compose existing transform with new one.
Affine Transform Matrices • Any affine transform can be represented by a 3x3 matrix. See chalkboard… (see also the AffineTransform API) • Composing a sequence of transforms corresponds to matrix multiplication.
Different Strokes • In the old AWT, lines were always 1-pixel wide, and you could only choose a single solid color (foreground and fill color). • Now, the Stroke class gives a vast number of potential outline styles, and the Paint class lets you draw and fill with patterns, gradients, images, etc.
BasicStrokes • Class BasicStroke implements Stroke • Lets you control curve width, dash pattern, and corner appearance. • Well documented on-line. JFC in a Nutshell provides nice pictures too.
Paint • Predefined implementations: Color, GradientPaint, TexturePaint. • Color: A solid color. • GradientPaint: Linearly interpolates colors between 2 given colors at 2 given points. Cycles or is solid beyond points. • TexturePaint: Tiles a BufferedImage in a specified rectangular pattern.
Specifying Colors • constants Color.pink, Color.black, etc. • Color(float r, float g, float b [, float a]) specifies red/green/blue/alpha each in range [0,1]. • Color JColorChooser.showDialog( Component component, String title, Color initialColor); (gets user’s color selection)
Alpha-Compositing • Compositing refers to superimposing one image on another. • In alpha-compositing, this is done by calculating the color of each pixel as a linear combination of the original color and the new color: C’ = (1-a)C1 + a C2 • The parameter a (should be alpha) varies from 0 to 1. Opaqueness factor.
Alpha-Compositing • Graphics 2D g2 = (Graphics2D)g;g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.5)); • Many images have an “alpha channel” which defines an alpha-value for each pixel. The Image and ColorModel classes provide built-in support for translucent images. (“RGBA”) • Example: Translucent GradientPaints.
RenderingHints • One of the most important new features. Request graphics methods with Graphics2D.setRenderingHint. • g.setRenderingHint( RenderingHint.KEY_ANTIALIASING, RenderingHint.VALUE_ANTIALIAS_ON); • g.setRenderingHint( RenderingHint.KEY_RENDERING, RenderingHint.VALUE_RENDER_SPEED);
Anti-aliasing • Reduces “jagginess” caused by sudden color changes at pixel borders, by making lots of minor changes to pixels. • Can greatly improve readability of rotated text, appearance of sharp borders. • May result in weird effects, especially if the background color changes. Demo
Image Classes • Image • BufferedImage extends Image • ImageIcon (a small fixed-size image) • RenderableImage, RenderedImage • ImageProducer, ImageObserver, ImageConsumer • ImageFilter
Images • Unlike ImageIcon, an Image is not a fixed-size picture. Image can be scaled to any size. The data for an Image may be present in memory, somewhere else on the internet, or generated on demand by an ImageProducer. • Prefer to work with BufferedImages. Stored locally; no latency issues.
BufferedImage • BufferedImages are represented by a ColorMap and a Raster of pixels, in memory. • Since they are in memory, there are many more methods to manipulate them, and fewer things to go wrong.
Loading a BufferedImage • First, load the picture as an Image. Methods for doing this on next slide. • Create a new BufferedImage of the same dimensions: Image.getHeight(); Image.getWidth(); new BufferedImage(w,h,TYPE_3BYTE_BGR); • Copy the image data. Graphics2D g = bufImage.getGraphics(); g.drawImage(Image);
Operations on any Image • Display. • Graphics.drawImage(Image,int x,int y); • Modify off-screen. • Image.getGraphics(); The returned Graphics object can be used to change the image. • Get dimensions. • Image.getWidth(); Image.getHeight();
Uses for BufferedImages • Use tiled image as a Paint. new TexturePaint(BufferedImage im, Rectangle r); • Convert to JPEG format. import com.sun.image.codec.jpeg.*; JPEGImageEncoder.encode(BufferedImage);
Support for other formarts • Go to www.google.com, search: “gif encoder java”. Lots of hits. • http://www.acme.com/java/software/ encoder/decoder for .gif, .ppm • http://www.geocities.com/morris_hirsch/java/how_to_print.html many useful classes for printing & image formats.
Double Buffering • Graphics computations can be very slow. In a long sequence of graphics ops, intermediate displays may be ugly. • Double buffering solves this by doing all the graphics ops on an undisplayed image, then “blitting” or copying the image to screen. • Trades memory & time for appearance.
Double Buffering in Swing • On by default. Can be turned off: JComponent.setDoubleBuffered(false); Turning this off may speed things up, but is probably not worth doing.