JavaFX ImageView显示高GPU
我正在创建JavaFX应用程序,并制作了一个加载场景。在这个场景中,我想显示一些文本,比如加载或初始化,并添加一些加载微调器动画图像,作为加载内容的视觉通知 我生成了一个通过创建的加载.gif动画,并将其像动画帧一样下载(多个.png文件) 我注意到,在JavaFX Scene Builder 8.5.0中,当我在ImageView中设置.gif时,我在NVidia GeForce RTX 2070图形卡上的Windows任务管理器中的GPU上升了20%,我认为这是一个问题。我使用javafx桌面应用程序进行了测试,以排除场景生成器应用程序产生的问题,并得到了类似的结果 我尝试的下一步是使用javafx创建自定义动画。动画。时间线。这是我从控制器初始化(URL位置,ResourceBundle资源)函数调用的初始化函数。此函数不使用.gif图像,而是使用同一.gif图像的多个.png图像作为帧JavaFX ImageView显示高GPU,java,animation,javafx,animated-gif,Java,Animation,Javafx,Animated Gif,我正在创建JavaFX应用程序,并制作了一个加载场景。在这个场景中,我想显示一些文本,比如加载或初始化,并添加一些加载微调器动画图像,作为加载内容的视觉通知 我生成了一个通过创建的加载.gif动画,并将其像动画帧一样下载(多个.png文件) 我注意到,在JavaFX Scene Builder 8.5.0中,当我在ImageView中设置.gif时,我在NVidia GeForce RTX 2070图形卡上的Windows任务管理器中的GPU上升了20%,我认为这是一个问题。我使用javafx桌
private void initializeAnimation() {
imgLoading.setCache(true);
imgLoading.setCacheHint(CacheHint.SPEED);
Image[] images = new Image[31];
for(int i = 0; i <= 30; i++){
images[i] = new Image(getClass().getResourceAsStream("/es/main/gui/javafx/images/loading/frame-" + i + ".png"));
}
Timeline timeLine = new Timeline();
Collection<KeyFrame> frames = timeLine.getKeyFrames();
Duration frameGap = Duration.millis(100);
Duration frameTime = Duration.ZERO;
for (Image img : images) {
frameTime = frameTime.add(frameGap);
frames.add(new KeyFrame(frameTime, e -> imgLoading.setImage(img)));
}
timeLine.setCycleCount(Timeline.INDEFINITE);
timeLine.play();
}
private void initializeAnimation(){
imgLoading.setCache(true);
imgLoading.setCacheHint(CacheHint.SPEED);
Image[]images=新图像[31];
对于(int i=0;i imgLoading.setImage(img));
}
timeLine.setCycleCount(timeLine.unfinite);
timeLine.play();
}
在第一个版本中,我没有调用.setCache()和.setCacheHint()函数,而是在测试同一代码的不同变体时添加了它们。我还尝试添加
-Dprism.forceGPU=true-Dsun.java2d.opengl=true-Dprism.order=es2、es1、sw、j2d
作为VMOption或我在本论坛上读到的关于改进java图形相关设置的一些变体。最后,在所有的更改之后,我的任务管理器中的结果并没有发生很大的变化。在当前版本中,我在这个场景中使用了高达17%的GPU
当场景结束时,在没有.gif图像或Timeline的下一个场景中,我的GPU几乎下降到0%
运行配置:
处理器:i9-9900KF
图形卡:GeForce RTX 2070
Java版本“1.8.0_251”
JavaFX版本“8.0.251-b08”
简短的总结问题:如何在JavaFX中正确显示动画.gif图像,而不会在GPU(或使用集成图形时的CPU)上产生巨大的开销
(编辑)14.09.2020-Java命名约定
我没有注意到的第一件事是,我在ImageView上没有使用相同的大小,因此我为测试更改的第一件事是将ImageView调整为与.gif图像相同的大小(ImageView和.gif图像的宽度和高度相同)。通过此更改,GPU百分比降低到大约%5
根据建议,我还升级了Java和JavaFX版本:
简短总结:升级Java和JavaFX版本并没有改变与此问题相关的任何内容。使用相同的大小会有所帮助,但我认为在您的帮助下,我可以做得更好。我的猜测是,如果您使用一个或多个
旋转平移
而不是关键帧动画,您可能会看到一些性能提升
下面是一个简单的示例,在一个场景中使用多个转换:
1.您真的认为在这样一个过时的JavaFX版本上研究性能问题值得吗?JavaFX15本周刚刚发布。2.为什么不提供一个小的、可复制的例子呢。这会增加你的机会,有人愿意花一些时间来分析你的问题。使用微调器的一帧并旋转它是个好主意,但它看起来不如我文章中链接中的动画好。在这个微调器中,如果你一帧一帧地分析图像,你会注意到它不仅会旋转,还会改变颜色的不透明度,但是对于简单的微调器来说,这是一个很好的主意。如果你想变得更有趣,你可以像和一样使用。我编辑了答案以适应。我将尝试,但我不确定为什么java在gif加载方面有问题。在过去,我在使用swing作为gui时遇到了类似的问题。
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 500, 200);
stage.setScene(scene);
Rectangle rect = new Rectangle (100, 40, 100, 100);
rect.setArcHeight(50);
rect.setArcWidth(50);
rect.setFill(Color.VIOLET);
RotateTransition rt = new RotateTransition(Duration.millis(3000));
rt.setByAngle(180);
rt.setAutoReverse(true);
FadeTransition ft = new FadeTransition(Duration.millis(3000));
ft.setFromValue(1.0);
ft.setToValue(0.3);
ft.setCycleCount(4);
ft.setAutoReverse(true);
ParallelTransition pt = new ParallelTransition(rect, ft, rt);
pt.play();
root.getChildren().add(rect);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}