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

java的graphics2d_Java Graphics2D 使用详解 | 学步园正如我们在前面提到的 我们可以对 Graphics2D 类进行多项设置 实际上 渲染引擎在绘制 Graphics2D 图形前会查看 7 个主要的属性 PaintStrokeF 让我们逐一讲解 Paint 新的 paint 可以同时作用在边线和填充上了 Graphics2D 类可以用 setPaint

正如我们在前面提到的,我们可以对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的实例。

Figure-3.gif

图 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 是以上各个选项的效果。

Figure-4.gif

图 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

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

Figure-5.gif

图 5. Alpha Composite的常用选项。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/223999.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午12:56
下一篇 2026年3月17日 下午12:56


相关推荐

  • 视频传输协议(常用的视频协议)

    SDP协议RTPRTCPSRTPRTP只负责传输数据包,需要与RTCP配合使用,由RTCP来保证RTP数据包的服务质量。每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前12个字节的含义是固定的,而负载则可以是音频或者视频数据。整个IP报文由IP报头、UDP报头、RTP报头、RTPPayload(音频或视频数据)组成, IP协议最大传输单元(MTU)最大为1500字节,其中包括至少20字节的IP头、8字节的UDP头、12字节的RTP头, 这样,头信息

    2022年4月17日
    106
  • 歌华有线财务分析报告(歌华有线机顶盒置换)

    网易科技讯3月2日动静,歌华有线宣布公司2010年业绩快报,公司去年完成净利3.45亿元,同比增长4.41%。公司完成业务支出18.94亿元,同比增长24.96%;每股收益0.325元,同比增长4.4%。有动静称,休止2010年12月31日,公司收到北京市各区县财务2010年岁字电视机顶盒补贴资金2.56亿元,预计增长2010年利润总额510万元。此前,公司已…

    2022年4月10日
    56
  • 详解EditText输入监听TextWatcher「建议收藏」

    日常开发中,我们可能会遇到需要监听EditText输入,比如判断输入是否为电话号码,获取输入的数据长度来限定字数等。这就需要监听EditText的输入状态。EditText使用TextWatcher实现类似按钮监听事件:使用方法效果图:MainActivity.javapublicclassMainActivityextendsAppCompatActivity{priv

    2022年4月16日
    41
  • GitHub 热榜:轻量级无 Agent 的自动化运维平台!「建议收藏」

    GitHub 热榜:轻量级无 Agent 的自动化运维平台!「建议收藏」大家好,我是JackTian。作为一名运维工程师,大家都知道。早在几年前,偏传统运维,以cacti、nagios为主流,到后来的zabbix、Prometheus、Open-Falcon等,也是现在大多数企业用的偏多的运维监控平台。甚至有些企业,都是自主研发。不管是自主研发还是用开源的,其最终目的都是为了提高日常运维工作效率。那么,今天杰哥给大家推荐一款GitHub热榜开源运维平台——spug。这款开源运维平台是:面向中小型企业设计的轻量级无Agent的自动化运维平台,其主要功能

    2022年5月13日
    60
  • Navicat_Premium激活码【2021最新】

    (Navicat_Premium激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~1S…

    2022年3月27日
    369
  • 创意的课程设计——憨憨钟设计(碾压)

    创意的课程设计——憨憨钟设计(碾压)目录写在前面的话设计的实际演示憨憨钟的主要功能设计的实现过程界面设计模型结构设计元件清单调试异常分析结语写在前面的话大家好,学习之余给大家分享一个这学期设计的课程设计,互相学习借鉴。课程设计,尤其是自定义的课程设计,自盘古开天地以来就困扰着每一位工科男。我,一枚工科男,觉得需要站出来为大家排忧解难了。这学期有自定义的课程设计,所以我就设计了一个很有创意的课程设计,是一个国外开源的设计,结合了国外开源资料和一些大佬的实践经验。设计的实际演示憨憨钟自动写时间的效果:憨憨钟的演示效果1憨憨钟自动画天气

    2022年5月20日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号