Java 2D API - 1. 基本概念

时间:2024-05-19 13:03:44

Java 2D API扩展AWT包,对二维图形、文本及成像功能提供了支持,可用于开发复杂的界面、绘图软件和图像编辑器。Java 2D对象位于用户坐标空间(User coordinate space),当对象呈现在屏幕或打印机,用户空间坐标转换为设备空间坐标(device space coordinate)。下面两个类对 Java 2D API十分重要:

  • Graphics
  • Graphics2D

Java 2D API提供了如下功能:

  • 为显示设备和打印机等提供了统一的渲染模型;
  • 提供了大量的几何图元(geometric primitive),如曲线(curves)、方形(rectangle)、椭圆(ellipse),并包含几乎可生成任何几何图形的机制;
  • 图形、文本和图像的hit detection 机制;
  • 用于重叠图像对象渲染的混合模型;
  • 增强颜色支持;
  • 打印复杂的文档;
  • 渲染的质量控制。

1. 坐标系

Java 2D API 包含两套坐标空间:

  • 用户空间(User space)  - 绘制图形区域坐标系统
  • 设备空间(Device space)  - 输出设备如屏幕、窗口或打印机的坐标系统

用户空间是编程时所使用的坐标空间,该坐标体系是一个与设备无关的逻辑坐标系统。

用户空间坐标的原点在左上角,x坐标向右递增,y向下递增,如下图所示。所有的坐标以整数指定(大多时候使用整数就足够了,也提供了float和double支持)。

Java 2D API - 1. 基本概念

设备空间与具体设备相关,虽然屏幕坐标系统和打印机的坐标系统相差很大,但是对Java程序没有任何影响,编程时完全不用考虑。

2.  Java 2D 渲染

Java 2D API为不同设备提供了统一的渲染模型,不管目标设备是打印机还是屏幕,渲染过程在API层次都是一样的。当需要显示某个组件,其paint() 或update() 方法都能以配置合适的Graphics 调用。

Graphics属性:

  • Color: 当前绘制颜色(java.awt.Color)。所有的绘制,着色和纯文本输出都将以指定的颜色显示;
  • Font:当前字体(java.awt.Font)。用于所有纯文本输出的字体。
  • Clip:java.awt.Shape类型,用于定义几何形状。该特性定义进行绘制的区域。通常这一形状与整个图形环境相同,但也不一定如此。
  • ClipBounds:java.awt.Rectangle对象,表示包围Clip属性所需的Shape类型的最小矩形。只读属性。
  • FontMetrics:java.awt.FontMetrics只读特性。该对象包含关于图形环境中当前起作用的Font的信息。获取该信息的机制被LineMetrics类取代。
  • Paint Mode:该特性控制环境使用当前颜色的方式。

Graphics2D类扩展Graphics类,提供了更多的图形绘制功能。包括:

  • stroke 和 paint属性(draw方法),用于渲染几何图元的边框;
  • paint 属性 (fill方法),使用特定颜色或图案填充图形;
  • font 属性,(drawString方法)渲染文本,通过font属性将字符串转换为字形(glyph),然后通过paint属性填充颜色或图形;
  • 渲染图像(drawImage方法)。

另外,Graphics2D还包含Graphics的方法,如drawOval, fillRect。

以上所有方法可以分为两类:

  1. 绘制图形的方法
  2. 渲染图形的方法

第二类方法通过设置 Graphics2D 的属性值实现以下渲染功能:

  • 改变笔画宽度
  • 改变笔画之间的连接方式
  • 指定需要渲染的区域
  • 对图形进行平移、旋转、缩放等
  • 设置图形填充的颜色和图案
  • 设置多个图形组合的方式

要使用Graphics2D的功能,需要对 Graphics 进行强制转换:

publicvoid paint(Graphics g){

Graphics2D g2 = (Graphics2D) g;

……

}

下面以具体图形展示 Graphics2D 的不同特性:

Java 2D API - 1. 基本概念

pen属性,应用于图形边框。该stroke属性允许以任意的点尺寸(point size)、虚线模式(dashing pattern) 、末端链接方式绘制线条。

Java 2D API - 1. 基本概念

fill属性,用于图形内部。该paint属性支持以纯色、渐变色或图纹等不同方式填充图形。

Java 2D API - 1. 基本概念

compositing属性,用于重合对象的渲染、

Java 2D API - 1. 基本概念

transform属性,将渲染对象从用户空间转换为设备空间时应用的属性。包括平移、渲染、缩放等。

Java 2D API - 1. 基本概念

clip属性,通过Shape对象指定需要渲染区域的。

Java 2D API - 1. 基本概念

font属性,将文本转换为字形(glyphs)。

Java 2D API - 1. 基本概念

渲染建议(Rendering hints),在渲染的速度和质量间进行取舍。例如,你可以指定是否使用反锯齿(antialiasing)。

3. 几何图形

Java 2D API提供了点、线、矩形、弧线、椭圆、曲线等一套标准的几何图形。这些基本图形都定义在 java.awt.gemo包中。任何其他的形状都可以通过这些基本图形进行组合获得。

Shape 接口表示一个几何图形,包含边框和内部区域。该接口定义的方法功能包括:描述和检查二维几何对象,支持曲线片段和图形子片段,而Graphics类只支持直线片段。

下面是对java.awt.geom 包中各个类的简介。

(AffineTransform, Arc2D, Area, CubicCurve, Dimension2D, Ellipse2D, FlatteningPathIterator, GeneralPath, Line2D, Path2D, QuadCurve, Rectangle2D, RectangularShape, RoundRectangle2D)

Java 2D API - 1. 基本概念

黄色部分是遗留类。

3.1 Points

Point2D 类定义了一个 (x,y) 坐标空间的点。在Java 2D API中 "point"不等价于 pixel。"point" 没有面积,不包含颜色,并且不能被渲染。

Points 用于创建其他的图形。 Point2D中包含一个计算两点之间距离的方法。

3.2 Lines

Line2D 是用于表示“线”的抽象类。线的坐标可以用 double 表示。Line2D类包含多个用于设置“线”终点的方法。也可以使用GeneralPath 类创建直线。

3.3 Rectangular Shapes

Rectangle2D, RoundRectangle2D, Arc2D和Ellipse2D 图元都扩展自 RectangularShape 类,该类实现了Shape接口。

Java 2D API - 1. 基本概念

3.4 Quadratic and Cubic Curves (二次和三次曲线)

QuadCurve2D 用于创建二次曲线。二次曲线通过两个端点和一个控制点定义。

CubicCurve2D 类用于创建三次曲线。三次曲线通过两个端点和两个控制点定义。

二次曲线

Java 2D API - 1. 基本概念

三次曲线

Java 2D API - 1. 基本概念

3.5 Arbitrary Shapes

GeneralPath类可用于创建任意形状。该类通过指定图形的边框创建任意形状。如,下图用三条直线和一条三次曲线创建曲线:

Java 2D API - 1. 基本概念

3.6 Areas

通过Area类,可以对两个Shape 对象执行布尔操作,如(合并、交叉、相减)。该技术,也被称为区域几何学(Constructive area geometry),可用来迅速创建复杂的图形。

4. 文本(Text)

Java 2D API包含许多文本渲染功能,如字符串渲染,字体设置以及文本布局。

绘制静态字符串方法:调用Graphics 类的 drawString方法。通过Graphics 的 setFont方法指定字体。

如果你需要实现自己的文本编辑程序,或需要更好的控制文本的布局,则可以使用 java.awt.font包中的类。

4.1 字体(Fonts)

字体中字符的形状的表示称为字形(glyph)。单个字符或多个字符可能以一个或多个glyph表示。例如, á可能以两个glyph表示,而连字fi则可能以一个glyph表示。

可以将字体(font)看做是一个glyph集合。一个字体可以包含多个属性(faces),如斜体(italic)、常规(regular)和加粗等,单个字体的不同faces具有类似的排版特性,因此可以看做是同一字体的成员。换句话说,特定风格的字形(glyph)集合构成一个font facefont face集合构成一个font familyfont family集合构成一个计算机上可用的所有字体。

Java 2D API通过Font实例指定字体。通过如下方法可以获得当前系统所有可用字体:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();

String[] fonts = ge.getAvailableFontFamilyNames();

for (String s : fonts) {

System.out.println(s);

}

4.2 文本布局(Text Layout)

在显示文本前,必须对其进行排版,以合适的字形显示对应的字符。下面是Java 2D 管理文本布局的两种机制:

  • TextLayout管理文本布局(text layout),文本高亮(highlighting)及hit detection。TextLayout可用于处理大部分情况,包括混合字体文本、混合语言和双向文本等。
  • 可以用于Font类创建自己的GlyphVector对象,然后使用Graphics2D类渲染GlyphVector。如此能够完全控制文本的形状和位置。

4.3 文本的渲染建议(Rendering Hints for Text)

Java 2D API 通过rendering hints控制图形和文本渲染的质量。Rendering hints封装在java.awt.RenderingHints类中。

对文本来说,该功能指反锯齿(也称为平滑边角)。例如,KEY_TEXT_ANTIALIASING可单独用于文本的平滑处理。

5. 图像(Images)

在Java2D API中,一张图片就是一个矩形的像素二维数组,每个像素(pixel)表示特定位置的颜色,而维度表示图片的宽度和高度。

java.awt.image.BufferedImage是表示图片最重要的类。Java2D API 通过BufferedImage表示图片将其载入内存,从而可以直接访问。

可直接创建BufferedImage,也可以通过载入外部图片(如PNG、GIF等)创建BufferedImage。

不管是哪种方式,Java2D API都允许在图片上进行绘制。所以,图形不局限于摄影类型图片,也包含弧线、文本甚至其他的图片,都可以绘制在一张图片上,如下所示:

Java 2D API - 1. 基本概念

Java 2D API允许对BufferedImage进行过滤,并且内置了许多过滤器。例如,ConsolveOp 过滤器可用于模糊(blur)或锐化(sharpen) 图片。处理后的图片可以输出到屏幕上,打印出来或者输出为PNG、GIF等格式进行保存。

6. 打印(Printing)

所有的Swing 和 Java 2D 图像(graphics), 包括复合(composited)图形图像,都可以通过Java2D Printing API到处到打印机。该API 还提供了组成文本的功能,从而可以对打印进行控制,如改变页面打印顺序等。

输出到打印机和输出到屏幕类似:打印系统控制页面何时打印,绘制系统控制一个组件何时在屏幕显示。

Java 2D Printing API 的打印系统使用callback模型控制页面的打印。通过应用程序提供待打印文本,打印系统控制何时对页面进行打印。

下面的两个特性对支持打印十分重要:

  • 任务控制(Job control) - 用于发起和控制打印任务,包括显示标准打印和设置对话框。
  • 页码导航(Pagination) - 在打印系统发出请求时,渲染每个页面。

当需要将页面图像化,打印系统以特定配置的Graphics调用应用的 print 方法。要使用Java 2D API特性,需要将Graphics 转换为Graphics2D,和绘图时一样。