【问题标题】:Alternatives to Canvas.snapshot() on JavaFXJavaFX 上 Canvas.snapshot() 的替代方案
【发布时间】:2016-10-11 08:40:08
【问题描述】:

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

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() 在每次执行中花费了太多时间,~14ms。我需要以至少 60fps 的速度更新画布,所以这几乎会消耗我必须绘制的所有时间。

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

【问题讨论】:

  • 尽管setFill(Paint),你还用SnapshotParameters做什么? AFAIK,您可以调整快照区域。您不必使用整个节点,也许这会给您一点动力。
  • 感谢您的想法。事实上我并没有使用SnapshotParameters ,所以我删除了它。我得到相同的图像结果。关于节点大小,画布应该和节点大小一样,所以我认为如果我指定快照区域,我应该有相同的性能。不管怎样,我会试试的。
  • 只是为了发布我上次的测试结果,如果我拍摄整个画布的快照,或者只拍摄其中的一部分,我会得到相同的性能。看起来我捕获哪个区域并不重要,这个过程需要时间才能完成。
  • 我以为离屏区域小于实际节点大小。但是,是的,如果两者相同,那根本没有区别。很抱歉。
  • 您尝试过使用 PixelWriter/Reader 吗? docs.oracle.com/javase/8/javafx/api/javafx/scene/image/…

标签: java performance canvas javafx


【解决方案1】:

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

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

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

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

然后使用以下命令将其打印在主画布上:

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

用图像填充所有画布。

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

希望对某人有所帮助。

【讨论】:

    猜你喜欢
    • 2017-12-13
    • 2018-06-16
    • 2015-06-13
    • 2019-04-22
    • 2018-08-07
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多