java 2d 教程_Java 2D开发技巧之“灯光与阴影”

a4c26d1e5885305701be709a3d33442f.png

Java 2D开发技巧之“灯光与阴影”

(2016-12-14 02:12:25)

标签:

杂谈

一、 引言

在本文中,我们将向你展示如何为扁平形状添加一种灯光效果以实现一种类3D外观。

也许你比较满意于自己的文字表达能力,但一幅图片往往能够产生更好的效果。对于图形处理来说,也是如此;不妨请参考一下图1中的两种图形。在本文中,我将向你展示如何克服左边扁平形状所带来的烦恼而以一种更为光滑的更具舒服感的形状代替。

图1.普通扁平形状与施加Java 2D效果后的形状

二、 实现技术分析

借助于适当的颜色,你可以使用本文中介绍的技术来模拟一种彩色光闪耀"越过"你的形状,从而生成一种微妙的发光效果。我们是如何实现这一效果的呢?请分析下面的代码;在方法drawBorderGlow上面的注释更为细致地介绍了关键实现方法:

import java.awt.geom.*;

import java.awt.image.*;

private

java视频教程

http://www.kgc.cn/java/list-1-6-9-9-0.shtml

static final Color clrHi=new Color(255, 229, 63);

private static final Color clrLo=new Color(255, 105, 0);

private static final Color clrGlowInnerHi=new Color(253, 239,

175, 148);

private static final Color clrGlowInnerLo=new Color(255, 209,

0);

private static final Color clrGlowOuterHi=new Color(253, 239,

175, 124);

private static final Color clrGlowOuterLo=new Color(255, 179,

0);

private Shape createClipShape {

float border=20.0f;

float x1=border;

float y1=border;

float x2=width - border;

float y2=height - border;

float adj=3.0f; //帮助圆化类锐的拐角

float arc=8.0f;

float dcx=0.18f * width;

float cx1=x1-dcx;

float cy1=0.40f * height;

float cx2=x1 dcx;

float cy2=0.50f * height;

GeneralPath gp=new GeneralPath;

gp.moveTo(x1-adj, y1 adj);

gp.quadTo(x1, y1, x1 adj, y1);

gp.lineTo(x2-arc, y1);

gp.quadTo(x2, y1, x2, y1 arc);

gp.lineTo(x2, y2-arc);

gp.quadTo(x2, y2, x2-arc, y2);

gp.lineTo(x1 adj, y2);

gp.quadTo(x1, y2, x1, y2-adj);

gp.curveTo(cx2, cy2, cx1, cy1, x1-adj, y1 adj);

gp.closePath;

return gp;

}

private BufferedImage createClipImage(Shape s) {

// 创建一半透明的中间图像,我们可以使用它来实现软修剪效果

GraphicsConfiguration gc=g.getDeviceConfiguration;

BufferedImage img=gc.createCompatibleImage(width, height,

Transparency.TRANSLUCENT);

Graphics2D g2=img.createGraphics;

//清除图像,这样所有的像素都具有零alpha

g2.setComposite(AlphaComposite.Clear);

g2.fillRect(0, 0, width, height);

// 把我们的修剪形状生成到图像上。注意,我们启动了

// 反走样功能以实现软修剪效果。你可以

//尝试注释掉启动反走样的这一行,那么

//你会看到通常的生硬的修剪效果.

g2.setComposite(AlphaComposite.Src);

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

g2.setColor(Color.WHITE);

g2.fill(s);

g2.dispose;

return img;

}

private static Color getMixedColor(Color c1, float pct1, Color

c2, float pct2) {

float clr1=c1.getComponents(null);

float clr2=c2.getComponents(null);

for (int i=0; i < clr1.length; i ) {

clr1[i]=(clr1[i] * pct1) (clr2[i] * pct2);

}

return new Color(clr1[0], clr1[1], clr1[2], clr1[3]);

}

//下面是实现技巧:为了实现发光效果,我们开始使用一种"内部"颜色粗笔

//和笔划需要的形状。然后,我们不断地把笔变细,

//并且不断地移向"外部"颜色,

//并且不断地提高颜色的不透明度以便使其朝向形状的内部看上去暗淡。

//我们使用已经生成到我们的目的图像上的"修剪形状",这样以来,

//SRC_ATOP规则就会修剪在我们的形状外部的笔划部分。

private void paintBorderGlow(Graphics2D g2, int glowWidth)

{

int gw=glowWidth*2;

for (int i=gw; i >=2; i-=2) {

float pct=(float)(gw - i) / (gw - 1);

Color mixHi=getMixedColor(clrGlowInnerHi, pct,clrGlowOuterHi,

1.0f - pct);

Color mixLo=getMixedColor(clrGlowInnerLo, pct,clrGlowOuterLo,

1.0f - pct);

g2.setPaint(new GradientPaint(0.0f, height*0.25f, mixHi,0.0f,

height, mixLo));

//g2.setColor(Color.WHITE);

g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,

pct));

g2.setStroke(new BasicStroke(i));

g2.draw(clipShape);

}

}

Shape clipShape=createClipShape;

//Shape clipShape=new Ellipse2D.Float(width/4, height/4, width/2,

height/2);

//把背景清除为白色

g.setColor(Color.WHITE);

g.fillRect(0, 0, width, height);

//设置修剪形状

BufferedImage clipImage=createClipImage(clipShape);

Graphics2D g2=clipImage.createGraphics;

//使用渐变填充形状

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

g2.setComposite(AlphaComposite.SrcAtop);

g2.setPaint(new GradientPaint(0, 0, clrHi, 0, height,

clrLo));

g2.fill(clipShape);

//应用边界发光效果

paintBorderGlow(g2, 8);

g2.dispose;

g.drawImage(clipImage, 0, 0, null);

注意,在上面的例子中,我把一些可选的代码行加上了注释。你可以去掉这些注释并观察它们对生成效果的影响。

注意:聪明的读者可以已经注意到,上面应用于paintBorderGlow方法中的技术也可以用于沿形状添加一种投影效果。你不妨先猜测一下如何实现这一点……好,时间到!不是在形状的顶部生成边缘(记住,修剪能够确保笔划仅影响形状的内部),我们可以预先绕着我们的形状生成一种可变的灰色边界。这意味着,阴影笔划将出现在我们的形状的外边;阴影笔划的内部将会通过我们的形状而有效地生成。

你可以把下面的一些代码插入到上面的例子中以便在相应的同一个形状上添加一种阴影边界效果:

private void paintBorderShadow(Graphics2D g2, int shadowWidth)

{

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

int sw=shadowWidth*2;

for (int i=sw; i >=2; i-=2) {

float pct=(float)(sw - i) / (sw - 1);

g2.setColor(getMixedColor(Color.LIGHT_GRAY, pct,Color.WHITE,

1.0f-pct));

g2.setStroke(new BasicStroke(i));

g2.draw(clipShape);

}

}

//在我们绘制形状的其它部分前应用边界的阴影效果。

paintBorderShadow(g, 6);

下面图2是最终的结果图像:

图2.施加Java 2D效果后的最终结果形状

三、 小结

在本文中,我仅向你介绍了快速地添加一种阴影效果的方法。如果有时间的话,我很可能会使用一种亮灰色和一种非线性斜面来实现一种更为真实的效果。还要注意的是,这里介绍的仅是使用Java

2D实现投影效果的许多方法之一。注意,Romain在他的博客中已经讨论了多种不同的投影实现方法。SwingLabs成员在SwingX工程中也提供了一种DropShadowBorder实现;而DropShadowPanel当前正在开发中。

分享:

a4c26d1e5885305701be709a3d33442f.png喜欢

0

a4c26d1e5885305701be709a3d33442f.png赠金笔

加载中,请稍候......

评论加载中,请稍候...

发评论

登录名: 密码: 找回密码 注册记住登录状态

昵   称:

评论并转载此博文

a4c26d1e5885305701be709a3d33442f.png

发评论

以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344497.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【渝粤教育】电大中专跨境电子商务理论与实务 (17)作业 题库

1.在按照交易主体类型中&#xff0c;&#xff08; &#xff09;面对的最终客户为企业或集团客户&#xff0c;提供企业、产品、服务等相关信息。 A.C2C跨境电商或平台 B.B2C跨境电商或平台 C.O2O跨境电商或平台 D.B2B跨境电商或平台 错误 正确答案&#xff1a;左边查询 学生答案…

jooq代码生成_将jOOQ与Spring结合使用:代码生成

jooq代码生成我们可能在本教程的第一部分中还记得jOOQ指出 jOOQ从您的数据库生成Java代码&#xff0c;并允许您通过其流畅的API构建类型安全SQL查询。 本教程的第一部分描述了如何配置使用jOOQ的Spring驱动的应用程序的应用程序上下文&#xff0c;但没有描述如何使用jOOQ创建类…

【渝粤题库】陕西师范大学151109财务报告分析 作业(高起专)

《财务分析》作业 一、单选题 1.以下哪个不属于杜邦分析法的优点&#xff08; &#xff09;。 2.以下哪个不是比率的具体表现形式&#xff08; &#xff09;。 3.根据财务报表的审计结果&#xff0c;具有较大可信度的审计意见类型是&#xff08; &#xff09;。 4.关于杠杆的…

【渝粤题库】陕西师范大学200131中国古代文论 作业(专升本)

《中国古代文论》作业 一、注明下列文献的作者及年代&#xff1a; 1、《典论论文》 2、《文选序》 3、《戏为六绝句》 5、《与元九书》 6、《送孟东野序》 7、《六一诗话》 8、《雪涛阁集序》 9、《文赋》 10、《诗品》 11、《诗品序》 12、《文心雕龙》 13、《沧浪诗话》 14、…

java连接到mysql_[操作系统]Java如何连接到MySQL数据库的

[操作系统]Java如何连接到MySQL数据库的0 2016-05-01 15:00:15下载&#xff1a;mysql-connector-java-5.1.38.tar.gzhttp://dev.mysql.com/downloads/connector/j/tar zxvfmysql-connector-java-5.1.38.tar.gz解压后zhouspubuntu:~/Downloads$cd ./mysql-connector-java-5.1.38…

Spark Run本地设计模式

现在&#xff0c;许多Spark应用程序已成为遗留应用程序&#xff0c;很难在本地进行增强&#xff0c;测试和运行。 Spark具有很好的测试支持&#xff0c;但仍有许多Spark应用程序不可测试。 当您尝试运行一些旧的Spark应用程序时&#xff0c;我将分享一个常见错误。 Exceptio…

【渝粤题库】陕西师范大学201771 中国古代文学(一) 作业

《中国古代文学&#xff08;一&#xff09;》作业 一、单选题&#xff08;共30小题&#xff0c;每题2分&#xff0c;共60分&#xff09; 1、先秦以“笔法”、“微言大义”著称于世的史书是&#xff08; &#xff09; A《尚书》 B《国语》 C《春秋》 D《战国策》 2、汉代“四家诗…

mave本地导入mysql的jar包_将本地的jar包引入到maven项目中

首先进入到maven的目录下&#xff0c;并且将要引入的jar包也放在这个目录下然后执行命令mvn install:install-file -DfilecheckDataAdapter-api.jar -DgroupIdorg.cegn.des -DartifactIdcheckDataAdapter-api -Dversion2.0 -Dpackagingjar等到success成功后&#xff0c;在maven…

【渝粤教育】广东开放大学 网页设计与制作 形成性考核 (25)

选择题 题目&#xff1a; 当链接指向下列哪一种文件时&#xff0c;不打开该文件&#xff0c;而是提供给浏览器下载&#xff1f;( ) 答案&#xff1a;看左侧 题目&#xff1a; 若要获得名为login的表单中名为txtuser的文本输入框的值&#xff0c;以下获取方法中&#xff0c;正…

mysql导入创建表空间_oracle创建表空间 导入数据库

oracle2 然后是创建表空间创建表空间需要创建两个一个临时表空间 一个表空间--创建表空间create tablespace abc datafile ‘D:\tablespce\LANDHIGH_SFTMS.dbf‘ size 500m;--创建用户并指定表空间create user admin identified by admin default tablespace abc quota 500m …

【渝粤教育】广东开放大学 软件工程 形成性考核 (50)

选择题 题目&#xff1a; 关于协作图的描述&#xff0c;下列哪个不正确&#xff08;&#xff09; 题目&#xff1a;多对象是UML哪个视图中的概念&#xff08; &#xff09;。 题目&#xff1a;在UML中&#xff0c;接口有几种表达方式&#xff08;&#xff09;。 题目&#xff1…

java集合根据值排序_Java 8:对集合中的值进行排序

java集合根据值排序意识到Java 8将在接下来的几周内发布其GA版本之后&#xff0c;我认为现在是时候来看看它了&#xff0c;在过去的一周里&#xff0c;我一直在阅读Venkat Subramaniam的书 。 我要讲的是第3章&#xff0c;它涉及对人员集合进行排序。 Person类的定义大致如下&…

【渝粤教育】广东开放大学民事诉讼法 形成性考核 (23)

选择题 题目&#xff1a; 调解的双方当事人依照人民调解等法律&#xff0c;自调解协议生效之日起三十日内&#xff0c;可共同向&#xff08; &#xff09;申请司法确认。 答案&#xff1a;看左侧 题目&#xff1a; 根据我国民事诉讼法的规定&#xff0c;当事人可以书面协议选…

【渝粤题库】广东开放大学 建筑制图 形成性考核

选择题 题目&#xff1a;标注坡度可用&#xff08;&#xff09;&#xff0c;百分数&#xff0c;分数等三种形式。 题目&#xff1a;以下哪种工具不属于常用绘图工具()。 题目&#xff1a;H面上产生的投影叫作&#xff08;&#xff09;。 题目&#xff1a;下列关于投影叙述正确的…

Java线程的不同状态

介绍 在Java中&#xff0c;线程可以具有状态。 Thread.State枚举定义Java线程可以具有的不同状态。 该枚举定义了以下值– 新 可运行 已封锁 等候 TIMED_WAITING 已终止 在接下来的部分中&#xff0c;我将简要概述这些状态以及它们之间的可能过渡。 Java线程的状态 新 …

【渝粤题库】广东开放大学 电子商务职业技能 形成性考核

选择题 题目&#xff1a;有形商品在线销售有两种形式&#xff0c;下列有一类与其它不相同的销售形式为 答案&#xff1a; A、一号店 B、优衣库 C、京东商城 D、当当网 题目&#xff1a;&#xff08; &#xff09; 互认识或不认识的消费者联合起来&#xff0c;加大与商家谈…

【渝粤题库】广东开放大学民法 形成性考核

选择题 题目&#xff1a;根据《合同法》的规定&#xff0c;下列合同中哪些属于有名合同&#xff1f; 题目&#xff1a;所谓合同的争议是指哪些争议&#xff1f; 题目&#xff1a;下列合同中&#xff0c;属于诺成合同的是 题目&#xff1a;甲百货商店与乙电视机厂订立买卖合同&a…

java中的双与_java 双冒号是什么操作符?

双冒号::在JDK8的Lambda表达式函数中开始使用&#xff0c;用作方法引用。具体用法&#xff0c;咱们来举个例子&#xff1a;假设有个Person类&#xff1a;public class Person {public enum Sex {MALE, FEMALE}String name;LocalDate birthday;Sex gender;String emailAddress;p…

【渝粤题库】陕西师范大学164104 网络财务管理 作业(高起专)

《网络财务管理》作业 一、选择题 1.财务管理网络化( )了地域限制&#xff0c;提高了信息传输速度&#xff0c;增加了信息的使用价值&#xff0c;降低了企业成本&#xff0c;并促使传统的财务管理演化为网络财务管理。 A.打破 B.连通 C.更新 D.重组 2.拥有雄厚的&#xff08; &…

q7goodies事例_Java 8 Friday Goodies:Lambda和SQL

q7goodies事例在 Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢 jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经 写了一些关于Java 8好东西的博客 &#xff0c;现在我们觉得是时候开始一…