用于服务器端映像生成的JavaFX
这听起来很奇怪,但我想使用JavaFX在服务器端生成图表图像。因为JavaFX有很好的画布API来执行图像转换、连接和定位 特别是,我有一个SpringMVC服务来将图表生成为图像。 主要问题是如何从方便的Springbean调用JavaFXAPI。 如果我尝试从java应用程序运行javafx代码(不扩展javafx应用程序类),我会得到用于服务器端映像生成的JavaFX,java,spring,image-processing,javafx-2,javafx,Java,Spring,Image Processing,Javafx 2,Javafx,这听起来很奇怪,但我想使用JavaFX在服务器端生成图表图像。因为JavaFX有很好的画布API来执行图像转换、连接和定位 特别是,我有一个SpringMVC服务来将图表生成为图像。 主要问题是如何从方便的Springbean调用JavaFXAPI。 如果我尝试从java应用程序运行javafx代码(不扩展javafx应用程序类),我会得到 您对如何解决这个问题有什么建议/想法吗?也许类似的解决方案会有所帮助 否则,我会考虑创建一个服务并将图像推送到数据存储区并在Spring应用程序中检索它。
您对如何解决这个问题有什么建议/想法吗?也许类似的解决方案会有所帮助
否则,我会考虑创建一个服务并将图像推送到数据存储区并在Spring应用程序中检索它。
希望至少能提供一点帮助 经过一些研究,我用JavaFX实现了画布绘制,下面是一个简化的示例: 首先,我制作了JavaFX应用程序,该应用程序将在单独的线程中启动(我使用Spring taskExecutor,但可以使用普通java线程) 然后,当Spring应用程序启动时,我调用initialize()方法:
@Autowired private TaskExecutor taskExecutor;
@PostConstruct private void initChartGenerator() {
ChartGenerator.initialize(taskExecutor);
}
此cource解决方案可以移植到非Spring应用程序
这是一个单线程解决方案(在我的例子中已经足够了),但我认为它可以用于多线程使用(可能使用RMI调用draw方法)
此外,此解决方案在我的windows工作站上“按原样”工作,但在linux服务器环境中,应调用一些其他操作:
另外,您还可以使用服务器端的其他JavaFX功能(例如,将html导出到图像)。如果其他人正在寻找,这是一种更简单的方法。 使用JavaFX2.2,我能够执行以下操作
waitForInit = new Semaphore(0);
root = new Group();
root.getChildren().add(jfxnode);
FxPlatformExecutor.runOnFxApplication(() -> {
snapshot = jfxnode.snapshot(new SnapshotParameters(), null);
waitForInit.release();
});
waitForInit.acquireUninterruptibly();
BufferedImage bi = SwingFXUtils.fromFXImage(snapshot, null);
无需将节点添加到组中。
从那里,您可以对图像执行任何操作
FxPlatformExecutor来自我在项目中使用的JME3-JFX库。
见:
您可以轻松创建runOnFxApplication()
方法或创建FxPlatformExecutor类
这是代码
package com.jme3x.jfx;
import javafx.application.Platform;
/**
* TODO This Class should be replaced by some Workmanager implemntation
* in the future
* @author Heist
*/
public class FxPlatformExecutor {
public static void runOnFxApplication(Runnable task) {
if (Platform.isFxApplicationThread()) {
task.run();
} else {
Platform.runLater(task);
}
}
}
我没有写这段代码,github链接在上面。这很酷。我很兴奋能尝试一下。谢谢你的努力!不必在(result==null)时使用
等待结果,而可以将提交到,如对的答复中所述。使用FutureTask应该更有效率,因为不会有繁忙的等待循环。这是一个不完整的示例,没有引用类FxPlatformExecutor-无法找到。感谢您指出这一点。导入是从我的项目中的第三方库中进行的,请参见。它很容易实现。我将把它添加到答案中。
waitForInit = new Semaphore(0);
root = new Group();
root.getChildren().add(jfxnode);
FxPlatformExecutor.runOnFxApplication(() -> {
snapshot = jfxnode.snapshot(new SnapshotParameters(), null);
waitForInit.release();
});
waitForInit.acquireUninterruptibly();
BufferedImage bi = SwingFXUtils.fromFXImage(snapshot, null);
package com.jme3x.jfx;
import javafx.application.Platform;
/**
* TODO This Class should be replaced by some Workmanager implemntation
* in the future
* @author Heist
*/
public class FxPlatformExecutor {
public static void runOnFxApplication(Runnable task) {
if (Platform.isFxApplicationThread()) {
task.run();
} else {
Platform.runLater(task);
}
}
}