java - JavaFX 上 Canvas.snapshot() 的替代品

标签 java performance canvas javafx

我正在使用 JavaFX 中的 Canvas 开发一个小型图形引擎。在某些时候,我不得不渲染一个屏幕外图像,然后使用它的 GraphicContext 在我的主 Canvas 上打印它。
我现在正在使用这段代码:

private Canvas offScreenCanvas;
private GraphicsContext offScreenGraphic;
private SnapshotParameters parameters;
private WritableImage offScreenImage;

[...]

offScreenCanvas = new Canvas(WIDTH, HEIGHT);
offScreenGraphic = offScreenCanvas.getGraphicsContext2D();

parameters = new SnapshotParameters();
parameters.setFill(Color.TRANSPARENT);

[...]

offScreenImage = offScreenCanvas.snapshot(parameters, offScreenImage);
graphic.setGlobalBlendMode(BlendMode.HARD_LIGHT);
graphic.drawImage(offScreenImage, 0, 0);
graphic.setGlobalBlendMode(BlendMode.SRC_OVER);

我的问题是 snaphot() 方法在每次执行时花费太多时间,大约 14 毫秒。我需要至少以 60fps 的速度更新 Canvas ,所以这几乎占用了我必须绘制的所有时间。

还有其他方法可以从 Canvas 获取 ImageWritableImage 吗?也许另一个不同的过程?

最佳答案

这是在不降低性能的情况下获得视觉等效结果的另一种方法。

我使用了 java.awt 类,而不是 JavaFX 类。 java.awt.image.BufferedImage 的创建提供了获取 java.awt.Graphics2D 的可能性,您可以在其中使用其他方法进行绘制。这里的主要问题是使用这个库绘制大图像会消耗大量时间,但您可以创建缩放图像。在我的例子中,我创建了一个四分之一大小的 BufferedImage,并使用该比例因子绘制了所有对象。

在绘制过程结束时,只需将 BufferedImage 转换为 javafx.scene.image.Image,使用:

 SwingFXUtils.WritableImage toFXImage(BufferedImage bimg, WritableImage wimg);

然后使用以下方法在主 Canvas 上打印它:

 graphic.drawImage(Image image, 0, 0, WIDTH, HEIGHT);

用图像填充所有 Canvas 。

最后,比例因子是可配置的,所以如果你需要一个详细的图像,就使用一个更高的值。对我来说,25% 大小的图像就足够了,因为我正在绘制渐变。现在,绘制图像需要 1-3 毫秒,这比以前好多了。

希望对大家有帮助。

关于java - JavaFX 上 Canvas.snapshot() 的替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39973435/

相关文章:

javascript - 尝试制作 Canvas "jump"

javascript - 为什么 clearRect() 没有完全清除 fillRect()

java - Android EditText 符号必须保持在初始位置

java - 将字符串转为数组并处理

java - 如何将 Java Swagger 注释转换为 Swagger json 模式?

java - Hashset 和 Arraylist 性能

ios - UIWebView 组件的启动时间?

java - 设计Java API

c++ - 使用 Eigen 的性能比使用我自己的类更差

javascript - 我可以检测鼠标当前是否在 Canvas 绘制函数内移动吗?