Java 2D 学习资料和API

关键词:Java2D,坐标转换,渲染,坐标系,字体

    Java 2D API增强了AWT的图形、文本和图像处理能力,使你能开发富客户界面和新类型的Java应用程序。
    除了这些丰富的图形、字体和图像处理接口,Java 2D API还支持增强的颜色定义及合成、任意形状和文本的边界检测及打印机和显示设备的统一渲染模型。
    Java 2D API还能使你创建高级图形库,如CAD-CAM库、图形图像特殊效果库、及创建图像和图形文件的读写过滤器等。
    当结合Java Media Framework及Java Media API一起使用时,Java 2D API能创建和显示动画以及其他多媒体的展现。Java Animation和Java Media Framework API要依赖于Java 2D API的渲染支持。

1.1增强的图形、文本和图像处理

    早期AWT版本只提供适合渲染普通HTML页面的简单渲染工具,功能并不足以渲染复杂的图形、文本和图像。早期AWT作为简化的渲染工具只包含通常渲染概念的某些特例情况。而Java 2D API提供更为灵活、功能更加完全的工具包,它扩展AWT支持更通用的图形和渲染操作。
    比如通过Graphics类,你可以画矩形、椭圆以及多边形。而Graphics2D增强了几何图形渲染概念,提供渲染任意几何图形的机制。与其类似使用Java 2D API你能画出任意样式、任意宽度的线,使用任意的纹理来填充各种几何图形。
    Java 2D通过对Shape接口的实现来提供几何图形渲染,比如Rectangle2D和Ellipse2D,甚至曲线和弧线也是Shape的具体实现。
    填充和笔画样式分别是通过实现Paint和Stroke接口提供的,如BasicStroke、GradientPaint、TexturePaint及Color。
    AffineTransform定义Java 2D坐标的线性转换(译者注:既仿射转换、射影几何学术语),包括缩放(scale)、位移(translate)、旋转(rotate)和剪切

(shear)四种转换。
    剪裁也是通过Shape接口来定义的,比如Rectangle2D和GerneralPath,Graphics通过它们来剪裁具体的区域。
    颜色合成通过实现Composite接口来提供,如AlphaComposite类。
    Font对象定义为一类字形(glyph)的集合,这些字形也是由Shape来描述的。

1.2渲染模型
    基本图形渲染模型并没因Java 2D API的出现而改变。为渲染某对象,首先你要建立图形上下文,然后用该Graphics对象激活某个渲染方法。
    Java 2D API的Graphics2D类扩展AWT的Graphics类以支持更多的图形属性,提供更多的渲染方法。关于如何建立Graphics2D上下文,参见第15页的“使用Grahphics2D渲染”一节。
    Java 2D API能自动为不同渲染设备消除差异,为不同类型的设备提供统一的渲染模型。在应用层,不管目标渲染设备,不管是打印机还是显示器,渲染过程都是相同的。
    Java 2 SDK 1.3的发布之后,Java 2D API提供多屏幕环境的支持。详细信息参见1.2.1小节“坐标系”“及多屏幕环境渲染”。

1.2.1坐标系
    Java 2D API使用两种坐标系:
    * 用户空间,是独立于设备的逻辑坐标系。应用程序使用该坐标系,所有传给Java 2D渲染过程的坐标都是指用户空间。
    * 设备空间,是设备相关的坐标系,随目标渲染设备不同而不同。
    支持虚拟桌面的多屏幕环境中,窗口能横跨不同物理屏幕,所使用的坐标系是包含所有屏幕的虚拟桌面的坐标系。关于Java 2D API如何支持多屏幕环境的详细信息,参见39页“多屏幕环境渲染”。
    Java 2D能为用户空间和目标渲染设备空间自动进行必要的坐标转换。尽管显示器的坐标系与打印机的坐标系不同,但是这些差异对应用程序都是不可见的。

1.2.1.1用户空间
    下图1-1所示,用户空间坐标系的原点在屏幕的左上角,x值由左至右变大,y值由上往下变大。

图1-1 用户空间坐标系
    用户空间代表所有设备坐标系的抽象。特定设备的空间可能与用户空间拥有相同的原点和方向,但也可能不同。不管怎样,当图形对象被渲染时,用户空间坐标总是被自动转换到合适的设备空间坐标。通常由底层平台的设备驱动来完成这一转换。

1.2.1.2 设备空间
    Java 2D API定义了三个层次的配置信息来维护从用户空间和设备空间之间的坐标转换信息。这些信息使用下面三个类封装:

    * GraphicsEnvironment
    * GraphicsDevice
    * GraphicsConfiguration

    GraphicsEnvironment、GraphicsDevice和GraphicsConfiguration描述定位渲染设备或Java平台字体,及从用户空间到设备空间坐标转换的所需信息。应用程序能访问这些信息,但不需要在用户空间和设备空间之间做任何转换。
    GraphicsEnvironment描述特定平台Java应用程序可见的渲染设备,比如屏幕、打印机以及图像缓冲。GraphicsEnvironment还能提供该平台所有可获得字体的列表。
    GraphicsDevice描述具体应用程序可见的渲染设备,如屏幕或者打印机。设备每种可能的配置使用GraphicsConfiugration来描述。比如SVGA显示设备能以几种不同的模式操作:640x480x16色、640x480x256色以及800x600x256色。每个SVGA屏幕用一个GraphicsDevice来描述,而每个显示模式用一个GraphicsConfiguration来描述。
    一个GraphicsEnvironment包含一个或者多个GraphicsDevice,同样每个GraphicsDevice能包含一个或者多个GraphicsConfiguration。

1.2.2转换
    Java 2D API有统一的坐标转换模型。所有的坐标转换包括从用户空间到设备空间的转换都用AffineTransform来表达。

    AffineTransform使用矩阵运算为坐标定义转换规则。
    你可以向图形上下文添加AffineTransform来实现几何图形、文字和图像的旋转(rotate)、缩放(scale)、位移(translate)和剪切(shear)等仿射转换。被添加的转换操作能作用到使用该上下文渲染的任意图形对象上。当用户坐标系转换到设备坐标系也会执行这个转换。

1.2.3字体
    字符串通常以组成该字符串的字符为单位进行考虑。当字符串被画出时,它的外观是由所选择的字体来决定的。但用来显示字符串的字体外形并不总和单个字符外形能一一对应的。比如在专业印刷中,某些两个或多个字符的组合通常会使用某种单一字形所替代,称作粘连(ligature)。
    字体用来表达字符串字符的图形称作字形(glyph)。字体可能会使用许多非常不同的字形表达同一个字符如a,或着使用某种字形组合表达粘连,如"final"中的使用一个字形表达的fi。在Java 2D API中,字形(glyph)其实是同其他Shape一样能进行操作和渲染的特殊Shape对象。
    字体是字形(glyph)的集合。一个字体可能有许多版本,比如粗重版(heavy)、中等版(medium)、倾斜版(oblique)、哥特体版(gothic)及规则版(regular)。这些不同版本的字形称作字面(faces)。同一字体的所有字面(face)拥有相似的拓扑结构,可被当作同一字体系(family)的成员。也就是说,相同风格的字形(glyph)集合构成字面(face),相同字体的字面(faces)集合构成字体系(family),字体系的集合构成特定GraphicsEnvironment所包含的字体库。
    在Java 2D API中,字体通过名字来描述某种字面(face),比如,Helvetica Bold。这同JDK 1.1中字体不同,JDK 1.1中将其描述成一个逻辑名称,这些逻辑名称是根据平台所能获得的字体而映射成的不同字面(faces)。
    使用Java 2D API能合成和渲染包含不同字体系(family)、字面以及尺寸的字符串。文本的外观同字体的布局在逻辑上是分开的。将字体和布局信息分开,能在使用不同布局配置参数时使用相同的字体。

1.2.4图像处理
    图像是按照特定空间方位组织起来的像素集合,每个像素定义特定位置上图像的外观,二维数组像素也称作光栅(raster)。
    像素可以直接使用颜色来定义,也可以使用图像颜色表(调色板)索引值来定义。
    在多颜色(多于256种)图像中,像素通常直接表达屏幕点的颜色、透明度及其它显示属性。这种类型的图像通常要比颜色索引编码的图像大得多,但能显得更加真实。
    在颜色索引编码的图像中,其颜色局限于颜色表所提供的色彩,这使得图像只能使用少数几种。但索引值比颜色值占用的空间要小,所以颜色索引编码存储的图像一般要小的多。这种格式通常只限於表达16或256种颜色的图像。
    Java 2D API图像处理有两个基本组件:

    * 原始图像数据(也称像素)
    * 解释像素所需信息

    解释像素的规则封装在ColorModel中,比如像素值是否解释为颜色值还是解释成索引值。像素须结合颜色模型才能显示。
    色带(band)是图像颜色空间的基本组成元素。比如红(Red)、绿(Green)和蓝(blue)是RGB类型图像的色带(band)。直接颜色模型的图像其像素可看作屏幕色带(band)数据的集合。
    java.awt.image含有几个ColorModel的实现,包含压缩类型和直接像素类型的。
    ColorSpace对象封装了如何管理颜色数值的规则。在java.awt.color中各种ColorSpace的实现定义了常见的颜色空间模型,如RGB和HSB。注意颜色空间不是某些颜色的集合,而是解释颜色值的规则。
    将颜色空间概念同颜色模型概念区分开,能灵活地表达颜色是如何显示的,以及一种颜色是如何转换到另一种颜色的。

1.2.5填充和笔画
    用Java 2D API可以以不同画笔样式及填充模式来渲染Shape对象。由于文字最终也以字形(Glyph, Shape的子类型)来渲染,字符串渲染也可使用各种笔画样式和填充模式。
    画笔样式由实现Stroke接口的对象来描述,笔画能为线段和曲线指定宽度和点画模式。
    填充模式由实现Paint接口的对象来描述。早期AWT版本中就有的Color类是Paint接口的一个简单实现,描述实体填充颜色。Java 2D API提供两种额外Paint实现,TexturePaint和GradientPaint。TexturePaint定义了用图像进行填充的模式(即纹理填充)。GradientPaint定义了用两种颜色的渐变模式(即渐变色填充)。
    Java 2D中渲染图形轮廓及用填充模式填充图形内部是两种不同的操作:

    * 用draw方法渲染几何图形的外观轮廓,可以用Stroke属性指定的画笔样式及Paint属性指定的填充模式。
    * 用fill方法填充几何图形的内部,可以用Paint属性指定fill的填充模式。

    在字符串渲染时,当前Paint属性能作用到被勾画文本的字形(glyph)上。注意drawString缺省行为是直接填充被渲染字形的内部(也就是非镂空文本)。如果要渲染字符串的轮廓,获得镂空文本显示,首先要获得他们的轮廓,然后使用draw方法作为普通的Shape进行渲染。

1.2.6合成
    当在现有对象之上渲染另一对象时,需要决定如何将新对象的颜色同已有对象的颜色合成。Java 2D API在Composite对象中封装了合成颜色的规则。
    底层渲染系统对合成颜色只提供布尔操作,布尔合成规则只允许源色和目标色进行AND、OR和XOR操作。使用此规则有以下几种缺陷:

    * 不直观。普通人难以想像红色和蓝色进行AND操作的结果。
    * 布尔合成操作不支持不同颜色空间的精确合成。
    * 直接的布尔合成没有考虑颜色模型。比如对索引颜色模型,其色素的布尔操作结果实际上是两个索引的合成,并非两种颜色的合成。

    Java 2D API实现了所谓alpha-blending的合成规则来避免以上缺陷,它在合成颜色时把当前颜色的模型和空间等因素也考虑在内。AlphaComposite对象既包含了源又包含了目标颜色的模型。

1.3兼容性及平台独立性
    Java 2D API同JDK 1.1保持了兼容性。同时它被设计成用其开发的应用程序能够保持平台独立性。

1.3.1兼容性
    为保证兼容性,现存JDK图形图像类及接口的功能仍然保留,即现存功能并没删除掉,现有类所在包的位置也没有变。Java 2D API增强了AWT的功能,它在现有类中添加新方法,扩展现有类,新增类和接口而不会影响已有的API。
    比如Java 2D API的许多功能是通过扩展图形上下文的Graphics2D提供的。为扩展图形上下文功能且同时保持兼容性,Graphics2D继承扩展了JDK 1.1的Graphics。
    图形上下文的使用模型没有发生任何改变,AWT使用以下的方法向AWT组件传递图形上下文:

    * paint
    * paintAll
    * update
    * print
    * printAll
    * getGraphics

    JDK1.1的Applet将传递给它的图形上下文解释成Graphics对象。如要在兼容Java 2D API的applet中使用Graphics2D提供的新功能,需将图形上下文转型成Graphics2D对象,代码如下:

    有些情况下Java 2D API并没有扩展现有类,而是泛化了它。有两种方法泛化现有类:

    * 在继承树上插入一个或多个中间父类,现有类继承新的父类。使用该方法来向现有类添加方法和实例数据。
    * 向现有类增加实现一个或多个接口。使用该方法来向现有类添加抽象方法。

    比如Java 2D API同时使用了这两种方法来泛化AWT的Rectangle类,此类现在的继承结构如下:

   JDK 1.1的Rectangle类只是简单继承了Object。现在它继承了新增的Rectangle2D类,并实现Shape接口和Serializable接口。Rectangle的继承树增添了两个父类: Rectangle2D及RectangleShape。为JDK1.1写的Applet意识不到新的父类和接口,但由于Rectangle仍保留着早期版本的方法和成员,所以应用程序不会受到任何影响。
    Java 2D API新增了几个类及接口,这些类和接口同现有API是正交的。新增类并不继承或泛化现有类,它们是全新不同的。这些新类和接口包含了老API中没有明确表达的概念。
    比如Java 2D API实现了几个新的Shape类,包括Arc2D、CubicCurve2D及QuadCurve2D等。尽管AWT早期版本能使用drawArc和 fillArc来渲染弧线,但没有通用的抽象曲线,也没有独立的类包含弧线。现在这些独立类能在不影响现有applet的情况下添加到Java 2D API中,这是因为drawArc和fillArc仍然是被Graphics类保留并支持的。

1.3.2平台独立性
    为能开发平台独立的应用程序,Java 2D API不对渲染设备的分辨率、颜色空间以及颜色模型做任何假设,也不对任何图像文件格式做任何假设。
    对于字体来说,真正的平台独立性只有当字体是内置时(作为JDK的一部分提供)、或者字体是用运算或编程产生时才有可能。Java 2D API目前不支持内置或运算产生的字体,但能使用字形集(glyph set)通过编程来定义字体。字形(glyph)由多条线段或曲线合成的Shape来定义,许多特定样式及尺寸的字体可以从字形集中产生。

1.4 Java 2D API包

    Java 2D API分为以下几个包:

        * java.awt
        * java.awt.geom
        * java.awt.font
        * java.awt.color
        * java.awt.image
        * java.awt.image.renderable
        * java.awt.print

    java.awt中包含一般或比原有增强的Java 2D API类和接口。(很显然不是所有java.awt 的类都是Java 2D类)。

java.awt.geom 是与几何图形定义相关的类和接口:

    很多图形都有相应的.Float和.Double的实现类,这样可以启用浮点数以及单、双精度的实现。双精度实现的渲染精确度比较高,但在某些平台上会降低性能。 java.awt.font 中包含有用于布局和字体定义的类和接口: 

java.awt.color 是用于颜色空间定义和颜色调优的类和接口:

java.awt.image 和 java.awt.image.renderable是用于图像定义和渲染的类和接口:

java.awt.image在AWT早期版本中就有。Java 2D API 对下面已有AWT图像类做了增强:

        * ColorModel
        * DirectColorModel
        * IndexColorModel

    java.awt.image包保留了这些颜色模型,保证兼容性。为保证一致性,新的颜色模型类位于 java.awt.image中。

    java.awt.print是用于打印所有基于 Java 2D 的文本、图形和图像的类和接口。


文章地址: http://javapub.iteye.com/blog/762151

你可能感兴趣的:(java,设计模式,jdk,编程,虚拟机)