技术标签: java 2d 教程
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当前正在开发中。
分享:
喜欢
0
赠金笔
加载中,请稍候......
评论加载中,请稍候...
发评论
登录名: 密码: 找回密码 注册记住登录状态
昵 称:
评论并转载此博文
发评论
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。
文章浏览阅读311次。我也是个新手所以遇到的问题可能不全面,不过确实有很多的坑,写下来,后面再补充第一步:找到b站安装视频https://www.bilibili.com/video/BV1oz411v7cv?from=search&seid=12498239426358158910第二步:按照上述步骤下载anaconda 这里指出官网下载需要注册,而恰巧你没有梯子,那么,你可以去清华的镜像网站 https://mirrors.tuna.tsinghua.edu.cn/anacon..._import pytorch as pytouch
文章浏览阅读1w次。尝试了很多网上的方法,反复提到找到 autodesk genuine service.msi 这个文件,但是电脑里没有这个文件只有autodesk genuine service.conf这个文件把他删了再去控制面板卸载就可以了_autodeskgenuineservice为什么卸载不掉
文章浏览阅读6.6w次,点赞12次,收藏102次。我们升级到鸿蒙3.0也面临着一个问题,那就是安装谷歌服务框架GMS谷歌play商店。在鸿蒙2.0的时候我们使用工具:华谷套件,列,X2,XS2。那么我们升级到鸿蒙3.0也面临着一个问题,那就是安装谷歌服务框架GMS谷歌play商店。在鸿蒙2.0的时候我们使用工具:华谷套件,同时配置电脑链接手机降级备份就可以安装Play商店。最新的好消息鸿蒙3.0也可以安装谷歌Play商店了,而且不需要使用电脑,只需要一个安卓APP:华谷套件,就可以轻松地安装。同时我找了几款其他的机型,比如mate 40系列都是可以安装的。_华为鸿蒙安装googleplay三件套
文章浏览阅读3.4k次,点赞4次,收藏25次。在打开示例工程的过程中,由于示例工程的源码是安装到根目录(/opt/)下的,所以不具有写权限,这时候QtCreator会弹窗提示,我们可以选择将其复制到家目录下自定义的目录中即可。如果是新安装的ubuntu操作系统,需将软件包源更换为国内对应ubuntu版本下的源,方便软件包的安装。注意如果不是以sudo进行安装,则不能在根目录(/)下创建目录,Qt默认安装路径目录也不是在。上图红框中是必须选择的,其他的组件就根据自己的实际需要选择啦,此处我选择了。方式进行安装,或者根据具体的依赖提示进行处理。......_ubuntu qt环境搭建
文章浏览阅读604次。函数原型:void *malloc(unsigned int num_bytes); //分配长度为num_bytes字节的内存块返回值是void指针,void* 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者其他数据类型),可以通过类型强制转化转化为其他任意类型指针。如果分配成功..._为什么要使用malloc
文章浏览阅读1k次,点赞25次,收藏19次。风速预测在可再生能源利用和电网稳定性方面至关重要。本文提出了一种基于秃鹰算法优化卷积神经网络结合支持向量机(BES-CNN-SVM)的多输入单输出风速预测方法。该方法充分利用了卷积神经网络的特征提取能力和支持向量机的回归能力,并通过秃鹰算法优化了模型超参数,提高了预测精度。引言风速预测是风能利用和电网稳定运行的关键技术。传统的风速预测方法通常基于统计模型或物理模型,但这些方法往往存在预测精度低、鲁棒性差等问题。近年来,机器学习技术在风速预测领域得到了广泛应用,表现出良好的预测效果。方法。
文章浏览阅读279次。Dymola是法国Dassault Systems(达索)公司的多学科系统快速设计和验证工具,广泛应用于国内外汽车、交通、能源等行业的系统总体架构设计、选型及匹配验证、系统优化、控制系统MIL/HIL验证等。_dymola
文章浏览阅读310次。Anonymous UUID: 9E5F7DE8-3A83-2978-8AC0-2FD1C1DC1171Thu Oct 8 23:36:14 2015*** Panic Report ***panic(cpu 0 caller 0xffffff8000816df2): Kernel trap at 0xffffff8000928ba2, type 14=pag..._fault cr2 fault cpu
文章浏览阅读1.8k次。Android SQL数据库操作(使用xUtils3)目录Android SQL数据库操作使用xUtils3目录基础配置基础类基本操作增保存一条数据保存一组数据删删除一条数据删除所有删除一组数据条件删除改修改一条数据批量修改数据查查询所有数据查询某条模糊查询条件查询分组查询查询数量其他排序指定数量指定位置基础配置xUtils3地址: https:_android sqlutil
文章浏览阅读927次,点赞11次,收藏10次。在Ubuntu中,反弹shell是指在远程服务器上建立一个与本地计算机的交互式连接,以便可以在远程服务器上执行命令和操作。这种连接通常是通过网络进行的,允许用户在不直接登录到远程服务器的情况下,进行远程管理和操作。反弹shell通常使用一些常见的工具和技术来实现,包括SSH、Netcat、Metasploit等。用户可以在本地计算机上直接操作远程服务器,执行命令、浏览文件等操作。需要注意的是,反弹shell可能存在安全风险,因此在实际使用中应当谨慎操作,并确保对服务器进行充分的安全防护。_ubuntu新增crontab反弹shell
文章浏览阅读95次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:java+ mybatis + Maven等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA。_小学在线考试系统
文章浏览阅读410次。今天是情人节,因为疫情的缘故我不能和可爱的小女友在一起过,手动悲伤……但是,依旧要为国家做贡献呀,同时,也希望有情人终成家属,我们的国家越来越好,当代的中国,太需要鲁迅的傲骨和钱学森式为祖国奉献的科学家了,最后给大家拜个晚年,开始吧!giao!example1这是没有任何过滤的SQL注入,我将会详细介绍这一个例子,接下来每一个例子只会介绍绕过方法(敲黑板)首先 root 后面加’ 判断是字符型:至于为何是--+ 注释而不是#,这里有必要参考一下这篇文章,实际做题中我建议三种注释都试试……_penteslab sql注入教程