Programming in Java Advanced Imaging
C H A P T E R10 |
Graphics Rendering |
THIS chapter describes the JAI presentation of rendering shapes, text, and images.
10.1 Introduction
JAI provides classes that support drawing operations beyond theGraphics2D
class. Three different types of graphics rendering are offered: simple 2D graphics, renderable graphics, and tiled image graphics. These are described in more detail in the sections that follow.
Figure 10-1 Simple Text and Line Added to an Image
10.1.1 Simple 2D Graphics
TheGraphics2D
class extends the even simplerGraphics
class to provide more control over geometry, coordinate transformations, color management, and text layout.Graphics2D
is the fundamental class for rendering two-dimensional shapes, text and images.Graphics2D
supports geometric rendering by providing a mechanism for rendering virtually any geometric shape, draw styled lines of any width, and fill geometric shapes with virtually any texture.The
BufferedImage.createGraphics
method creates aGraphics2D
object, which can then be used to draw into thisBufferedImage
.Geometric shapes are provided through implementations of the
Shape
interface, such asPolygon
,Rectangle
,CubicCurve2D
, andQuadCurve2D
. Fill and pen styles are provided through implementations of thePaint
andStroke
interfaces. For example, thePaint
interface supportsColor
,GradientPaint
, andTexturePaint
. TheStroke
interface supportsBasicStroke
, which defines a set of attributes for the outlines of graphics primitives.Text is added to graphics using the
Font
class, which represents character fonts. AFont
is defined by a collections ofGlyphs
, which in turn are defined by individualShapes
. Since text is represented by glyphs, text strings can also be stroked and filled like other geometric objects.
10.1.2 Renderable Graphics
TheRenderableGraphics
class is an implementation ofGraphics2D
withRenderableImage
semantics. This means that content may be drawn into the image using theGraphics2D
interface and later be turned intoRenderedImages
with different resolutions and characteristics.The
RenderableGraphics
class allows you to store a sequence of drawing commands and "replay" them at an arbitrary output resolution. By serializing an instance ofRenderableGraphics
, you create a kind of metafile for storing the graphical content.The methods in the
RenderableGraphics
class override the methods in thejava.awt.Graphics
andjava.awt.Graphics2D
classes. This means that you can use the methods inRenderableGraphics
to set your fonts and colors, to create the graphics shapes and text, define a clipping path, and so on.The only method unique to
RenderableGraphics
is thecreateRendering
method, which creates aRenderedImage
that represents a rendering of the image using a givenRenderContext
. This is the most general way to obtain a rendering of aRenderableImage
.
10.2 A Review of Graphics Rendering
To render a graphic object, you set up theGraphics2D
context and pass the graphic object to one of theGraphics2D
rendering methods. Before rendering the graphic object, you first need to set certain state attributes that define how theGraphics2D
context displays the graphics. For example, you specify:
- The stroke width
- How strokes are joined
- A clipping path to limit the area that is rendered
- Define colors and patterns to fill shapes with
Graphics2D
defines several methods that add or change attributes in the graphics context. Most of these methods take an object that represents a particular attribute, such as aPaint
orStroke
object.
10.2.1 Overview of the Rendering Process
When a graphic object is rendered, the geometry, image, and attribute information are combined to calculate which pixel values must be changed on the display.The rendering process for a
Shape
is described into the following four steps:1. If the
Rendering text is similar to rendering aShape
is to be stroked, theStroke
attribute in theGraphics2D
context is used to generate a newShape
that encompasses the stroked path.2. The coordinates of the
Shape
's path are transformed from user space into device coordinate space according to the transform attribute in theGraphics2D
context.3. The
Shape
's path is clipped using the clip attribute in theGraphics2D
context.4. The remaining
Shape
is filled using thePaint
andComposite
attributes in theGraphics2D
context.
Shape
, since the text is rendered as glyphs and each glyph is aShape
. However, you still must specify whatFont
to use for the text and get the appropriate glyphs from theFont
before rendering. The attributes are described in more detail in the following sections.
10.2.2 Stroke Attributes
TheGraphics2D
Stroke
attribute defines the characteristics of strokes. TheBasicStroke
object is used to define the stroke attributes for aGraphics2D
context.BasicStroke
defines characteristics such as line width, endcap style, segment join style, and pattern (solid or dashing). To change theStroke
attribute in theGraphics2D
context, you call thesetStroke
method.
10.2.2.1 Line Width
The line width is specified in points (there are 72 points to the inch). To set the stroke width, create aBasicStroke
object with the desired width and callsetStroke
. The following example sets the stroke width to 12 points.
wideStroke = new BasicStroke(12.0); g2.setStroke(wideStroke);10.2.2.2 Endcap Style
Table 10-1 lists the endcap style attributes.
To set the endcap style, create a
BasicStroke
object with the desired attribute. The following example sets the stroke width to 12 points and endcap style is set toCAP_ROUND
.
wideStroke = new BasicStroke(12.0, BasicStroke.CAP_ROUND); g2.setStroke(roundStroke);10.2.2.3 Join Style
Table 10-2 lists the join style attributes. These attributes affect the appearance of line junctions.
To set the join style, create a
BasicStroke
object with the desired attribute. The following example sets the stroke width to 12 points, an endcap style ofCAP_ROUND
, and a join style ofJOIN_ROUND
.
wideStroke = new BasicStroke(12.0, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); g2.setStroke(roundStroke);10.2.2.4 Stroke Style
The stroke style is defined by two parameters:
dash
- an array that represents the dashing pattern. Alternating elements in the array represent the dash size and the size of the space between dashes. Element 0 represents the first dash, element 1 represents the first space.Listing 10-1 shows a code sample in which two different dashing patterns are created. In the first pattern, the size of the dashes and the space between them is constant. The second pattern uses a six-element array to define the dashing pattern. The two dash patterns are shown in Figure 10-2.
dash_phase
- an offset that defines where the dashing pattern starts.
Listing 10-1 Example Stroke Styles
// Define the first dashed line. float dash1[] = {10.0f}; BasicStroke bs = new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f); g2.setStroke(bs); Line2D line = new Line2D.Float(20.0f, 10.0f, 100.0f, 10.0f); g2.draw(line); // Define the second dashed line. float[] dash2 = {6.0f, 4.0f, 2.0f, 4.0f, 2.0f, 4.0f}; bs = new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash2, 0.0f); g2.setStroke(bs); g2.draw(line);
Figure 10-2 Example Stroke Styles
10.2.2.5 Fill Styles
ThePaint
attribute in theGraphics2D
context defines the fill color or pattern used when text andShape
s are rendered.
Filling a Shape with a Gradient
TheGradientPaint
class allows a shape to be filled with a gradient of one color to another. When creating aGradientPaint
object, you specify a beginning position and color, and an ending position and color. The fill color changes proportionally from one color to the other along the line connecting the two positions, as shown in Figure 10-3.In all three stars, the gradient line extends from point P1 to point P2. In the middle star, all of the points along the gradient line extending to the left of P1 take the beginning color and the points to the right of P2 take the ending color.
Figure 10-3 Filling a Shape with a Gradient To fill a shape with a gradient of one color to another:
1. Create a
Listing 10-2 shows sample code in which a rectangle is filled with a blue-green gradient.GradientPaint
object2. Call
Graphics2D.setPaint
3. Create the
Shape
object4. Call
Graphics2D.fill(shape)
Listing 10-2 Example Filling a Rectangle with a Gradient
GradientPaint gp = new GradientPaint(50.0f, 50.0f, Color.blue, 50.0f, 250.0f, Color.green); g2.setPaint(gp); g2.fillRect(50, 50, 200, 200);
Filling a Shape with a Texture
TheTexturePaint
class allows you to fill a shape with a repeating pattern. When you create aTexturePaint
, you specify aBufferedImage
to use as the pattern. You also pass the constructor a rectangle to define the repetition frequency of the pattern.To fill a shape with a texture:
1. Create a
Listing 10-3 shows sample code in which a shape is filled with texture.TexturePaint
object2. Call
Graphics2D.setPaint
3. Create the
Shape
4. Call
Graphics2D.fill(shape)
Listing 10-3 Example Filling a Shape with Texture
// Create a buffered image texture patch of size 5 X 5. BufferedImage bi = new BufferedImage(5, 5, BufferedImage.TYPE_INT_RGB); Graphics2D big bi.createGraphics(); // Render into the BufferedImage graphics to create the texture. big.setColor(Color.green); big.fillRect(0, 0, 5, 5); big.setColor(Color.lightGray); big.fillOval(0, 0, 5, 5); // Create a texture paint from the buffered image. Rectangle r = new Rectangle(0, 0, 5, 5); TexturePaint tp = new TexturePaint(bi, r, TexturePaint.NEAREST_NEIGHBOR); // Add the texture paint to the graphics context. g2.setPaint(tp); // Create and render a rectangle filled with the texture. g2.fillRect(0, 0, 200, 200); }
10.2.3 Rendering Graphics Primitives
TheGraphics2D
class provides methods for creatingShape
s andText
, and for renderingImages
. Table 10-3 lists these methods.
10.2.3.1 Drawing a Shape
TheGraphics2D.draw
method is used to render the outline of anyShape
. TheGraphics2D
class also inherits draw methods from theGraphics
class, such asdrawLine
,drawRect
,drawRoundRect
,drawOval
,drawArc
,drawPolyline
,drawPolygon
, anddraw3DRect
.When a
Shape
is drawn, its path is stroked with theStroke
object in theGraphics2D
context. (See Section 10.2.2, "Stroke Attributes," for more information.) By setting an appropriateBasicStroke
object in theGraphics2D
context, you can draw lines of any width or pattern. TheBasicStroke
object also defines the line's endcap and join attributes.To render a
Shape
's outline:1. Create the
Listing 10-4 shows a code example in which aBasicStroke
object2. Call
Graphics2D.setStroke
3. Create the
Shape
4. Call
Graphics2D.draw(shape)
GeneralPath
object is used to define a star and aBasicStroke
object is added to theGraphics2D
context to define the star's line width and join attributes.
Listing 10-4 Example Drawing a Shape
public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; // Create and set the stroke. g2.setStroke(new BasicStroke(4.0f)); // Create a star using a general path object. GeneralPath p new GeneralPath(GeneralPath.NON_ZERO); p.moveTo(- 100.0f, - 25.0f); p.lineTo(+ 100.0f, - 25.0f); p.lineTo(- 50.0f, + 100.0f); p.lineTo(+ 0.0f, - 100.0f); p.lineTo(+ 50.0f, + 100.0f); p.closePath(); // Translate the origin towards the center of the canvas. g2.translate(100.0f, 100.0f); // Render the star's path. g2.draw(p); }
10.2.3.2 Filling a Shape
TheGraphics2D.fill
method is used to fill anyShape
. When aShape
is filled, the area within its path is rendered with thePaint
object in the Graphics2D context: aColor
,TexturePaint
, orGradientPaint
.The
Graphics2D
class also inherits fill methods from theGraphics
class, such asfillRect
,fill3DRect
,fillRoundRect
,FillOval
,fillArc
,fillPolygon
, andclearRect
.To fill a
Shape
:1. Set the fill color or pattern on the
Listing 10-5 shows a code example in which theGraphics2D
context usingGraphics2D.setColor
, orGraphics2DsetPaint
.2. Create the
Shape
3. Call
Graphics2D.fill
to render theShape
setColor
method is called to define a green fill for aRectangle2D
.
Listing 10-5 Example Filling a Shape
Public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setpaint(Color.green); Rectangle2D r2 = new Rectangle2D.float(25, 25, 150, 150); g2.fill(r2); }
10.2.3.3 Rendering Text
The entire subject of fonts and text layout is too extensive to try to describe here. In this section, we'll give a brief overview of theGraphics2D.drawString
method, which is used to render a text string.There are two basic variations on the
drawString
method. Two methods takes aString
for an argument and two methods take anAttributedCharacterIterator
. If the argument is aString
, the currentFont
in theGraphics2D
context is used to convert the characters in theString
into a set of glyphs with whatever basic layout and shaping algorithms the font implements. If the argument is anAttributedCharacterIterator
, the iterator is asked to convert itself to aTextLayout
using its embedded font attributes. TheTextLayout
implements more sophisticated glyph layout algorithms that perform Unicode I-directional layout adjustments automatically for multiple fonts of differing writing directions.A third method used to render text is the
Graphics2D.drawGlyphVector
method, which takes aGlyphVector
as an argument. TheGlyphVector
object contains the appropriate font-specific glyph codes with explicit coordinates for the position of each glyph.The character outlines are filled with the
Paint
object in the Graphics2D context.
10.3 Graphics2D Example
Listing 10-6 shows a code sample for a Graphics2D example.
Listing 10-6 Graphics2D Example
// Read a RenderedImage and convert it to a BufferedImage. imagePath = new String("./images/sample.jpg"); Image ai = loadAWTImage(imagePath, this); RenderedImage ri = JAI.create("awtimage", ai); BufferedImage bi = getBufferedImage(ri); RenderedImage targetImage = null; targetImage = new BufferedImage(bi.getWidth(), bi.getHeight(), bi.getType()); // Create a Graphics2D object to draw into the BufferedImage. Graphics2D g2d = targetImage.createGraphics();
10.4 Adding Graphics and Text to an Image
Thejava.awt.Graphics2D
class enables you to draw lines, geometric shapes, images, and text. These objects can then be "painted" over aTiledImage
.
Programming in Java Advanced Imaging
Copyright © 1999, Sun Microsystems, Inc. All rights reserved.
Casa de Bender