Java 2D - How the Graphics2D Class Renders
 
正如我们在前面提到的,我们可以对Graphics2D类进行多项设置。实际上,渲染引擎在绘制Graphics2D图形前会查看7个主要的属性:
Paint
Stroke
Font
Transformation
Clipping space
Rendering hints
Compositing rule

让我们逐一讲解:

Paint
新的paint可以同时作用在边线和填充上了。Graphics2D类可以用setPaint()和getPaint()方法配制paint属性:

      g2.setPaint(java.awt.Paint paint);Paint paint = g2.getPaint();

paint可以是单色,渐变和图案。任何paint都需要实现java.awt.Paint接口。

Java 2D类库中有三个类你应该感到熟悉:
java.awt.Color:
Java 2D使用同样的常量。因为Color类实现了java.awt.Paint接口,所有的Color对象都是Paint对象。
java.awt.GradientPaint:
这个类用颜色渐变填充一个区域。构造函数制定比例和颜色。图形引擎会从第一个点到第二个点之间线性变化两个颜色。我们还可以指定颜色图案是否允许重复。
java.awt.TexturePaint:
这个类平铺一个图像来填充图形。构造函数接收一个java.awt.image.BufferedImage和一个Rectangle2D,把图像影射到矩形里,然后平铺矩形。

图3 显示java.awt.GradientPaint和java.awt.TexturePaint的实例。

图 3. GradientPaint 和 TexturePaint

建立一个BufferedImage来保存图像相对是更直接的方法。在BufferedImage的构造函数里制定长,宽,高,类型为BufferedImage.TYPE_INT_RGB,然后调用createGraphics()方法得到一个Graphics2D。

如果要用图片的话就需要更多的步骤。首先,从一个图片文件里读入Image对象,用MediaTracker保证图片完全读入,然后建立和Image对象等宽高的空BufferedImage对象。通过createGraphics()方法得到Graphics2D对象,最后把Image对象加载到bufferedImage里。

Stroke
描边决定着图形或文字的轮廓。通过setStroke()方法定义描边::

      g2.setStroke(java.awt.Stroke stroke);java.awt.Stroke stroke = g2.getStroke();

在Java 2D出现以前,java.awt.Graphics的描绘方法产生一个1像素宽的实线边。Java 2D API给你更灵活的描边选择。边缘即可以是粗细不等的实线,也可以是等宽点线。

setStroke()方法的参数必须实现java.awt.Stroke接口。现在java.awt.BasicStroke类是唯一实现的类。下面是BasicStroke的构造函数:
BasicStroke():
这个构造建立一个1单位宽的描边。端点样式是默认的CAP_SQUARE,默认接头样式是默认的 JOIN_MITER。
BasicStroke(float penWidth):
指定线宽,端点样式使用默认的CAP_SQUARE,默认接头样式使用默认的 JOIN_MITER。
BasicStroke(float penWidth, int capStyle, int joinStyle):
指定线宽,端点样式和接头样式。
BasicStroke(float penWidth, int capStyle, int joinStyle, float miterLimit):
基本同上,但可以设置拼接连接的延长度,默认是10。
BasicStroke(float penWidth, int capStyle, int joinStyle, float miterLimit,
float[] dashPattern, float dashOffset):
这个构造可以通过一个表明[透明,不透明的]数组,建立点线轮廓。offset是点线的起始位置,一般是0,0。

正如这5个构造函数所示,BasicStroke类允许设定端点样式。型如下:
java.awt.BasicStroke.CAP_BUTT: 端点直接切断。
java.awt.BasicStroke.CAP_ROUND: 以线宽为直径的圆形端点。
java.awt.BasicStroke.CAP_SQUARE: 半线宽单位延伸的方块端点。

BasicStroke 还可以指定端点的连接样式,斜角,拼接和圆角:
java.awt.BasicStroke.JOIN_BEVEL: 用直线连接两条线的外角。
java.awt.BasicStroke.JOIN_MITER: 延伸外角直至两线相接。
java.awt.BasicStroke.JOIN_ROUND: 半线宽单位的圆形封顶。

图 4 是以上各个选项的效果。

图 4. BasicStroke 的 Cap 和 Join 选项。

下面的例子用BasicStroke生成点线:

Stroke stroke = new BasicStroke(5.0f ,                   // 线宽BasicStroke.CAP_ROUND,   // 端点BasicStroke.JOIN_MITER, // 接头15.0f,                   // 拼接限制new float[] {10.0,10.0} // 点线图案5.0);                    // 定位

我们再看一下最后三个属性:
拼接限制可以避免当两条线以JOIN_MITER连接且角度很小的时候,延伸的很夸张。点线图案是一个浮点数组,第一个是实线的长度,第二个是间断的长度。不断重复描绘实线和间断实现点线效果。最后的定位设置了位移,即线的起始点。

Font
所有的文本都使用能表现文字的样式图形渲染。当前的字体决定了字体的形状。使用继承自java.awt.Graphics的getFont()方法和setFont()方法来操纵字体。尽管设置字体相对简单的工作,Java 2D还是为文本描绘提供了丰富的选线。本文的后续版本会深度讨论这个问题。

Transformation
图形在渲染前可能会进行一步或多步的变形。简单而言就是图形可能被移动,旋转或拉伸。可以通过setTransform()方法设置当前的变形:

     g2.setTransform(java.awt.geom.AffineTransform transform);AffineTransform transform = g2.getTransform();

Graphics2D类提供许多方便的方法帮助实现变形。

     public void rotate(double theta);public void rotate(double theta, double aroundPointX, double aroundPointY);public void scale(double scaleX, double scaleY);public void shear(double shearX, double shearY);public void translate(double translateX, double translateY);public void transform(AffineTransform transform);

同样,你也可以直接操纵数字矩阵来实现复杂变形。这要比使用基本的变换,旋转,缩放,倾斜变形等复杂的多。更多关于线性代数的知识超出了本文的讨论范围,在Java 2D API里会对此有说明。一旦你熟悉了这些概念,它们可以有效地帮你实现变形。

java.awt.AffineTransform类提供了大量的变形控制,可以唯一可实现和上文提到的矩阵能实现的复杂变形的类。通过AffineTransform类的静态方法可以得到一个AffineTransform对象,如AffineTransform.getRotateInstance(....),或AffineTransform.getShearInstance(...),或者不带参的构造函数创建单位变形。

   AffineTransform newTransformation = new AffineTransform();

单位变形包含一个单位矩阵,该矩阵保留原始矢量且不可被操作变形。可以用下面的方法修改变形行为:

     public void rotate(double theta);public void rotate(double theta, double aroundPointX, double aroundPointY);public void scale(double scaleX, double scaleY);public void shear(double shearX, double shearY);public void translate(double translateX, double translateY);

此外,用下面的方法可以重值单位变形。setToIdentity()方法是个例外,它执行了一个简单变形。

     public void setToIdentity();     public void setToRotation(double theta);public void setToRotation(double theta, double aroundPointX, double aroundPointY);public void setToScale(double scaleX, double scaleY);public void setToShear(double shearX, double shearY);public void setToTranslation(double translateX, double translateY);

你还可以连接或预连接其他AffineTransform类。这样不仅仅是精确控制变形顺序,而是创建了变形序列(例如变换->旋转->变换->缩放...)。使用下面的方法连接或预连接:

     public void concatenate(AffineTransform transform);public void preConcatenate(AffineTransform transform);

Clipping Space
如果渲染操作在当前的剪辑空间外,则任何像素不会被改变。当前默认的剪辑空间是null,即修改整个图像表层。可以用setClip()方法设置当前的剪辑空间,该方法继承自java.awt.Graphics:

     g2.setClip(Shape clip);g2.setClip(int x, int y, int width, int height);Shape clip = g2.getClip();

此外,Graphics2D类提供了chip()方法,可以把传入的图形和当前剪辑空间的交集设置为新的剪辑空间。

     g2.clip(Shape s);

图形既可能是矩形之类的简单图形,也可能是字母数字之类的复杂图形。通过剪辑,可以选择或排出会受影响的像素。

Rendering Hints
Rendering hints是Graphics2D对象描绘基本类型时使用的各种描绘方法。如先前使用的抗锯齿hint。这些hints被封装在java.awt.RenderingHints类中。由于使用Java 2D API会比旧的AWT涉及更多的计算,设计师默认禁止了一部分特性以提高性能。两个最常用的设置是抗锯齿(混合锯齿柔滑锯齿线)和高质量渲染,如下:

      RenderingHints renderHints =new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);renderHints.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);...public void paintComponent(Graphics g) {super.paintComponent(g);Graphics2D g2d = (Graphics2D)g;g2d.setRenderingHints(renderHints);...}

其他渲染hints适用在不同的环境下。如缩放图片时,为KEY_INTERPOLATION使用VALUE_INTERPOLATION_BILINEAR。请查阅本类的Javadoc,详细了解各个选项所适用的环境。

Compositing Rule
组合规则决定图形之间颜色的相互影响。例如图片或图形的不透明度属于整个分类。以下方法可以得到组合规则:

    g2.setComposite(java.awt.Composite composite);Composite composite = g2.getComposite();

Java 2D允许分配透明(alpha)值,以便底层的图形可以显示出来。通常我们会创建一个java.awt.AlphaComposite对象,然后传入setComposite()方法的实现。

通常,用AlphaComposite.getInstance()方法,配合一定的混合规则和透明度值,创建AlphaComposite对象。Java 2D内建了一些符合 Porter-Duff 组合规则的混合规则。但在处理不透明时,通常会使用AlphaComposite.SRC_OVER。透明值由透明到不透明是在0.0和1.0之间。下面是完整的列表:

     AlphaComposite.CLEAR   - 交集部分的颜色和透明被清除。AlphaComposite.DST   - 目标未修改。AlphaComposite.DST_ATOP   - 目标和源重叠的部分组合在源上。AlphaComposite.DST_IN   - 显示目标和源重叠的部分。AlphaComposite.DST_OUT   -显示目标没有和源重叠的部分。AlphaComposite.DST_OVER   - 目标覆盖在源之上。AlphaComposite.SRC   - 源复制给目标。AlphaComposite.SRC_ATOP   - 源和目标重叠的部分组合在目标上。AlphaComposite.SRC_IN   - 显示源和目标重叠的部分。AlphaComposite.SRC_OUT   - 显示源没有和目标重叠的部分。AlphaComposite.SRC_OVER   - 源覆盖在目标之上。

图 5 是几个常用选项的图形效果。

图 5. Alpha Composite的常用选项。

Graphics2D 使用详解 【转】相关推荐

  1. java的graphics2d_Java Graphics2D 使用详解 | 学步园

    正如我们在前面提到的,我们可以对Graphics2D类进行多项设置.实际上,渲染引擎在绘制Graphics2D图形前会查看 7个主要的属性: Paint Stroke Font Transformat ...

  2. java制作海报一:java使用Graphics2D 在图片上写字,文字换行算法详解

    文章目录 前言 一.直接上代码 1. 写字方法 2. 换行算法 二. 叙述换行算法 前言 代码都上传到GitHub了,这里仅仅是贴出来主要部分,GitHub传送门:https://github.com ...

  3. 对接微信支付之网页支付详解

    对接微信支付之网页支付详解 声明:转载请注明出处 阅读对象:本文针对的是网页中的扫码支付 温馨提示:微信支付坑比较多,阅读时请仔细一些,不要放过所有需要注意的内容 , 本人一路踩坑过来,希望大家引以为 ...

  4. JDK安装和环境变量配置(Win10图文详解)

    JDK的安装和环境变量配置(Win10,图文详解) 操作系统 JDK的安装 JDK下载 系统环境变量配置 验证JDK和环境变量配置 Eclipse安装 Java小白入门项目代码参考 结语 操作系统 W ...

  5. 【Java网络编程与IO流】Java之Java Servlet详解

    Java网络编程与IO流目录: [Java网络编程与IO流]Java中IO流分为几种?字符流.字节流.缓冲流.输入流.输出流.节点流.处理流 [Java网络编程与IO流]计算机网络常见面试题高频核心考 ...

  6. JavaWeb详解加实战

    JavaWeb 1.基本概念 1.1.前言 web开发 web,网页的意思 静态web HTML.CSS 提供给所有人看的数据始终不变 动态WEB 提供给所有人看的数据始终会发证变化,每个人在不同的时 ...

  7. 从命令行到IDE,版本管理工具Git详解(远程仓库创建+命令行讲解+IDEA集成使用)

    首先,Git已经并不只是GitHub,而是所有基于Git的平台,只要在你的电脑上面下载了Git,你就可以通过Git去管理"基于Git的平台"上的代码,常用的平台有GitHub.Gi ...

  8. JVM年轻代,老年代,永久代详解​​​​​​​

    秉承不重复造轮子的原则,查看印象笔记分享连接↓↓↓↓ 传送门:JVM年轻代,老年代,永久代详解 速读摘要 最近被问到了这个问题,解释的不是很清晰,有一些概念略微模糊,在此进行整理和记录,分享给大家.在 ...

  9. docker常用命令详解

    docker常用命令详解 本文只记录docker命令在大部分情境下的使用,如果想了解每一个选项的细节,请参考官方文档,这里只作为自己以后的备忘记录下来. 根据自己的理解,总的来说分为以下几种: Doc ...

最新文章

  1. 协同过滤算法 R/mapreduce/spark mllib多语言实现
  2. PCA降维原理及其代码实现(附加 sklearn PCA用法参数详解)
  3. python报告 No module named 'main'错误
  4. 数据库SQL,技巧篇
  5. 计算机专业女兵,陈豪2010《点解阿Sir》剧照
  6. 图例放在图的外面_Qt编写自定义控件41-自定义环形图
  7. 机器学习数学基础(偏差方差、最大似然估计、贝叶斯统计、MAP)
  8. ubuntu升级11.10登录桌面
  9. eclipse打不开,报错 java was started with exit code=13
  10. OsmocomBB编译及GSM嗅探问题(转)
  11. USACO 3.2 msquare 裸BFS
  12. yagmail群发邮件
  13. 注册表java参数_Java通过CMD方式读取注册表任意键值对代码实践
  14. 雷达篇(四)雷达工作波段
  15. android手写计算器,MyScript Calculator(高级手写计算器) V1.2.2.479 安卓版
  16. 转:德鲁克:放弃昨天,是变革的第一原则
  17. 超说网络NO.4 | 深入了解应用层原理(中科大 郑烇)
  18. 今年这情况。。咱还是留个心眼吧
  19. VS2005 设置DLL程序无入口点
  20. Android如何获得Root权限来卸载程序?

热门文章

  1. 谁在“盘”物联网的“网”?
  2. 图像处理 图像相似算法aHash、dHash、pHash解析与对比
  3. 2022年最新前端零基础学习路径
  4. 对“主数据”的一点吐槽
  5. JavaScript-- 基础知识面试题
  6. 苹果隐藏应用_AppStore今日推荐 资源丰富无限制的隐藏观影应用
  7. py文件编译为pyc(命令与脚本)
  8. 计算机进去bios方式,两种使用的电脑进入BIOS方法
  9. 计算机专业毕业后的工作方向
  10. xp系统查找局域网计算机名,WinXP系统内网IP查询的方法