ImageVerifierCode 换一换
格式:DOCX , 页数:11 ,大小:30.66KB ,
资源ID:9379632      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9379632.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(JavaFX实现水波效果.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

JavaFX实现水波效果.docx

1、JavaFX实现水波效果JavaFX实现水波效果public class JfxRipper extends Application private final double MAX_WIDTH = 400.0; private final double MAX_HEIGHT = 400.0; private static AnimationTimer timer; private static AnimationTimer rainTimer; private FileChooser fc; private double scaleRate; private int maxRainSize,

2、 maxRainPower, stoneSize, stonePower; private int imgWidth, imgHeight; int arrWaveCurrent;/ 当前帧各点波动能量数据 int arrWaveNext;/ 下一帧各点波动能量数据 private Image img; private WritableImage imgRipper; private ImageView imgView; Override public void init() throws Exception fc = new FileChooser(); /添加文件类型过滤 fc.getEx

3、tensionFilters().add( new FileChooser.ExtensionFilter(图片文件, *.jpg;*.png;*.jpeg;*.bmp); img = new Image(getClass().getClassLoader().getResourceAsStream(images/红花.jpg); imgWidth = (int) img.getWidth(); imgHeight = (int) img.getHeight(); /波纹效果计算需要遍历图片每个像素,图片尺寸过大会导致运行速度极慢,故按比例缩小 if (imgWidth MAX_WIDTH |

4、 imgHeight MAX_HEIGHT) double sx = MAX_WIDTH / imgWidth; double sy = MAX_HEIGHT / imgHeight; scaleRate = sx sy ? sy : sx; img = scaleImg(img, imgWidth, imgHeight, scaleRate); imgWidth = (int) (scaleRate * (double) imgWidth); imgHeight = (int) (scaleRate * (double) imgHeight); maxRainSize = 4; maxRai

5、nPower = 60; stoneSize = 5; stonePower = 128; else /雨点和石子大小根据图片尺寸的大小稍作调整 maxRainSize = 3; maxRainPower = 50; stoneSize = 4; stonePower = 108; imgRipper = new WritableImage(imgWidth, imgHeight); arrWaveCurrent = new intimgWidth * imgHeight; arrWaveNext = new intimgWidth * imgHeight; imgView = new Ima

6、geView(); imgView.setOnMousePressed(new EventHandler() Override public void handle(Event event) MouseEvent e = (MouseEvent) event; dropStone(int) e.getX(), (int) e.getY(), stoneSize, stonePower); ); timer = new AnimationTimer() Override public void handle(long now) genRipper(); imgView.setImage(imgR

7、ipper); ; rainTimer = new AnimationTimer() Override public void handle(long now) rain(); imgView.setImage(imgRipper); ; /* * 模拟下雨,随机抛出不同大小和位置的石子 */ protected void rain() int x = (int) (Math.random() * imgWidth); int y = (int) (Math.random() * imgHeight); int rainSize = (int) (Math.random() * maxRain

8、Size); int power = (int) (Math.random() * maxRainPower) + maxRainPower; dropStone(x, y, rainSize, power); Override public void start(Stage primaryStage) throws Exception Group root = new Group(); VBox vb = new VBox(10); root.getChildren().add(vb); imgView.setImage(img); Scene scene = new Scene(root)

9、; primaryStage.setScene(scene); HBox hb = new HBox(10); Button rainControl = new Button(停止下雨); rainControl.setOnAction(ActionEvent event) - if (开始下雨.equals(rainControl.getText() rainTimer.start(); rainControl.setText(停止下雨); else rainTimer.stop(); rainControl.setText(开始下雨); ); Button changePic = new

10、Button(更换图片); changePic.setOnAction(ActionEvent event) - File f = fc.showOpenDialog(primaryStage); if (null != f) /将默认目录设置为上次访问过的目录 fc.setInitialDirectory(f.getParentFile(); /Image imgTmp = null; try img = new Image(new FileInputStream(f); /Desktop.getDesktop().open(f); catch (Exception e) e.printSt

11、ackTrace(); if (img != null) imgWidth = (int) img.getWidth(); imgHeight = (int) img.getHeight(); if (imgWidth MAX_WIDTH | imgHeight MAX_HEIGHT) double sx = MAX_WIDTH / imgWidth; double sy = MAX_HEIGHT / imgHeight; scaleRate = sx sy ? sy : sx; img = scaleImg(img, imgWidth, imgHeight, scaleRate); imgW

12、idth = (int) (scaleRate * (double) imgWidth); imgHeight = (int) (scaleRate * (double) imgHeight); maxRainSize = 4; maxRainPower = 60; stoneSize = 5; stonePower = 128; else maxRainSize = 3; maxRainPower = 50; stoneSize = 4; stonePower = 108; imgRipper = new WritableImage(imgWidth, imgHeight); arrWave

13、Current = new intimgWidth * imgHeight; arrWaveNext = new intimgWidth * imgHeight; imgView.setFitHeight(imgHeight); imgView.setFitWidth(imgWidth); primaryStage.setWidth(imgWidth); imgView.setImage(img); primaryStage.setHeight(imgHeight + 40); ); Button exit = new Button(退出); exit.setOnAction(ActionEv

14、ent event) - primaryStage.close(); ); hb.getChildren().addAll(rainControl, changePic, exit); vb.getChildren().addAll(imgView, hb); primaryStage.setWidth(imgWidth); hb.setAlignment(Pos.CENTER); scene.setFill(Color.BLUEVIOLET); primaryStage.initStyle(StageStyle.TRANSPARENT); timer.start(); rainTimer.s

15、tart(); primaryStage.show(); /* * 水波算法,原作者Imagic */ public void genRipper() PixelReader readImg = img.getPixelReader(); PixelWriter writeRipper = imgRipper.getPixelWriter(); int index = imgWidth; int indexPreX = index - 1; int indexNextX = index + 1; int indexPreY = index - imgWidth; int indexNextY

16、= index + imgWidth; for (int y = 1; y imgHeight - 1; y+) for (int x = 1; x 1) - arrWaveNextindex; / 波能衰减 1/32 arrWaveNextindex -= arrWaveNextindex 5; / 计算出偏移象素和原始象素的内存地址偏移量 : int xoffset = x2 - x1; int yoffset = x4 - x3; int offset = imgWidth * yoffset + xoffset; int posY = index / imgWidth; int pos

17、X = index - posY * imgWidth; int newY = (index + offset) / imgWidth; int newX = (index + offset) - newY * imgWidth; / 判断坐标是否在窗口范围内 if (index + offset 0 & index + offset imgWidth * imgHeight) writeRipper.setColor(posX, posY, readImg.getColor(newX, newY); else writeRipper.setColor(posX, posY, readImg.

18、getColor(posX, posY); / 交换波能数据缓冲区 int temp = arrWaveCurrent; arrWaveCurrent = arrWaveNext; arrWaveNext = temp; /* * 模拟向水中投石子 * * param x:石子位置X坐标 * param y:石子位置y坐标 * param stoneSize:石子半径 * param power:波能大小 */ private void dropStone(int x, int y, int stoneSize, int power) int minPosX = x - stoneSize,

19、maxPosX = x + stoneSize; int minPosY = y - stoneSize, maxPosY = y + stoneSize; minPosX = minPosX 0 ? 0 : minPosX; minPosY = minPosY imgWidth ? imgWidth : maxPosX; maxPosY = maxPosY imgHeight ? imgHeight : maxPosY; int value = stoneSize * stoneSize; for (int posx = minPosX; posx maxPosX; posx+) for (

20、int posy = minPosY; posy maxPosY; posy+) if (posx - x) * (posx - x) + (posy - y) * (posy - y) value) arrWaveCurrentposy * imgWidth + posx = -power; /* * 按比例缩小图片 * 缩小图片算法:x0 = x / sx, y0 = y / sy。x0,y0分别为原图水平和垂直索引, * sx,sy分别为水平和垂直缩小比例 * param src:原始图片 * param imgW:原始图片宽度 * param imgH:原始图片长度 * param r

21、ate:缩小后的图片不原图片尺寸的比例 * return 缩小后的图片 */ private Image scaleImg(Image src, int imgW, int imgH, double rate) int width = (int) (double) imgW * rate); int height = (int) (double) imgH * rate); WritableImage imgScaled = new WritableImage(width, height); PixelReader readSrc = src.getPixelReader(); PixelWr

22、iter writeDest = imgScaled.getPixelWriter(); for (int x = 0; x width; x+) for (int y = 0; y height; y+) writeDest.setColor(x, y, readSrc.getColor(int) (x / rate), (int) (y / rate); return imgScaled; public static void main(String args) launch(args); 里面用到了行序优先一维数组存储二维数组时两个数组索引之间的算术关系公式。设一维数组索引为index,二维数组行索引为x,列索引为y,均从0开始,每行存储元素个数为width,则: y = int(index / width),int为取整函数,如int(1.1)和int(1.9)都等于1 x= index - y * width index = width * y + x 截图:

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1