Lecture 7 Graphics under AWT Graphics Attributes Shapes Clips Affine Transformations Strokes,...

43
Lecture 7 Graphics under AWT Graphics Attributes Shapes Clips Affine Transformations Strokes, Paints, Colors, Translucency RenderingHints, Anti-aliasing Importing and Exporting Graphics Double Buffering
  • date post

    21-Dec-2015
  • Category

    Documents

  • view

    217
  • download

    0

Transcript of Lecture 7 Graphics under AWT Graphics Attributes Shapes Clips Affine Transformations Strokes,...

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.

Shape drawing/filling/erasing. Text drawing Image drawing Hit detection (do 2 shapes overlap?)

Graphics2D Methods

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.

Graphics2D Attributes

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).

The infinite plane

This pixel has corners(2,6), (3,6), (2,7) and (3,7).Pixels are the same as 1x1

rectangles.

0 1 2 3 4 5 6 7 8 9

10

2

-1

3

8

-2

4

9

56

7

-2-1 ...

121110

Another pixel, with top-left corner (7,-2)

The point (8.7, 3.4)Actual points have no height or width.

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.

Shape Hierarchy

Shape

Line2DRectangularShape

RoundRectangle2D

Rectangle2D, Rectangle

Ellipse2DArc2D

Polygon

QuadCurve2D

CubicCurve2D

GeneralPath

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

The infinite graphics plane

Screenrectangle

Only those pixels inside the “screen rectangle” are visible.Similarly, each Component has its own rectangle.

The clip rectangle

Theplane

ClipRectangle

Each Component has its own Graphics object, whichhas 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

1. 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.

2. 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

1. Your BinocularsComponent already displays something like this.

2. 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

Antialiased text close-up

Antialiased line close-up

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, .ppmhttp://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.