使用Java FX在服务器端生成映像

时间:2013-12-04 08:56:25

标签: java javafx javafx-2

目前我正在研究Jax Rs应用程序,我想将Base64编码的图像输出到客户端。客户端是移动设备。

移动设备将使用一些参数调用此服务,服务器必须绘制条形图并将其作为base64编码的图像字符串发送回设备。

由于java Fx具有所需的图表库,我使用以下教程做了一个示例。 “快照”功能也按预期正常工作(创建屏幕图像)。

http://docs.oracle.com/javafx/2/charts/bar-chart.htm#CIHJFHDE

现在我想在不扩展Application类的情况下这样做,因为我需要在Jax Rs应用程序中使用它。这样我就可以使用api创建一个BuffredImage然后用它来创建Base64字符串。

我找到了一种使用JFreeChart做到这一点的方法。但我更喜欢我能用Java FX做到这一点。我之前没有使用Java Fx的经验

请咨询

1 个答案:

答案 0 :(得分:8)

基于服务器的JavaFX运行时初始化

要在服务器上运行JavaFX,您需要:

  1. 启动JavaFX Application
  2. 使用JFXPanel
  3. 这些是在JavaFX 2中初始化JavaFX运行时系统的唯一方法,以便您可以使用它。

    与使用JavaFX应用程序相比,使用JFXPanel的处理效率可能略低。

    有关StackOverflow问题中JavaFX系统初始化的进一步讨论:JavaFX 2.1: Toolkit not initialized

    JavaFX是单线程系统

    您可以在任何线程中创建大多数JavaFX组件。但是,要在场景中呈现组件,必须在JavaFX Application线程上执行工作。这意味着如果您有一个多线程服务器进程(大多数服务器都是这样,并且您想要生成多个图表),则需要使用并发约束单独绘制图表呈现请求。

    1. 当您收到图表的传入请求时,请发出Platform.runLater命令。 runLater块中的所有代码都将放在最终将在JavaFX应用程序线程上运行的队列中。
    2. 在runLater块中为图表创建场景并将其快照到图像。 callback version of snapshot可能是最适合在这里使用的,因为它可能不会尽可能多地占用JavaFX应用程序线程,尽管它可能很难使用。
    3. 使用SwingFXUtils.fromFXImage将JavaFX图像转换为AWT图像。
    4. 要将您的图像结果返回到服务器处理程序线程中,请使用sarcan概述的FutureTask技术:Return result from javafx platform runlater
    5. 然后,您的服务器处理程序线程可以使用ImageIO将AWT图像转换为输出流,格式为png。您可以获取结果流和Base64 encode it并让服务器返回基本64位编码的流以响应原始图像请求调用。

      确保正常关机

      您需要在服务器启动时调用Platform.setImplicitExit(false)并注册一个关闭钩子或监视servlet何时被销毁的ServletContextListener,以便您也调用Platform.exit()关闭JavaFX系统。如果你不这样做,可能你的服务器将无法干净地关闭,因为JavaFX应用程序线程将继续运行等待工作。

      JavaFX 2.2并未真正获得在无头服务器上运行的认证

      使用系统属性run in headless mode,Swing应用程序可以java.awt.headless。我不知道JavaFX有类似的属性,虽然可能有一个,如果有的话,你可以通过询问openjfx-dev mailing list找出它是什么。

      JavaFX主要设计为客户端图形工具包。虽然您可能会在服务器上运行并运行满意的应用程序,但为此,您可能需要确保服务器未设置为headless server并且它具有适当的图形加速卡以提供负载下的合理性能。

      您可以在JavaFX issue tracker中提交正式支持无头模式的请求。