CSPP 533 - People.cs.uchicago.edu

advertisement
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
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.
Component.paint(Graphics g);
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
(foreground, background)
Line style (Stroke)
For drawing lines,
Fill style (Paint)
shapes and text
Composite (translucency effects)
Also for images
AffineTransform (rotation, translation, scaling)
Font (for drawing text)
Clip Region (Shape): Graphics directives
outside this region will be ignored.
RenderingHints: Antialiasing, speed, etc.
Color
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
Another pixel, with top-left corner (7,-2)
-2
-1
-2 -1 0 1 2 3 4 5 6 7 8 9 ...
0
1
2
The point (8.7, 3.4)
3
Actual points have
4
no height or width.
5
6
7
8
9
10
11
12
This pixel has corners
(2,6), (3,6), (2,7) and (3,7).
Pixels are the same as 1x1
rectangles.
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
RectangularShape
Line2D
QuadCurve2D
Polygon
CubicCurve2D
Arc2D
Ellipse2D
Rectangle2D, Rectangle
RoundRectangle2D
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
Screen
rectangle
Only those pixels inside the “screen rectangle” are visible.
Similarly, each Component has its own rectangle.
The clip rectangle
The
plane
Clip
Rectangle
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
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();
compose existing
Graphics2D.rotate();
transform
Graphics2D.scale();
with new one.
Graphics2D.shear();
Graphics2D.transform();
Graphics2D.getTransform();
Graphics2D.setTransform();
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 1pixel 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.getInstan
ce(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, .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.
Download