【问题标题】:Generating image at server side using Java FX使用 Java FX 在服务器端生成图像
【发布时间】:2013-12-20 16:12:17
【问题描述】:

目前我正在开发 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 经验

请指教

【问题讨论】:

标签: java javafx javafx-2


【解决方案1】:

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

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

  1. 启动 JavaFX Application
  2. 使用JFXPanel

这些是在 JavaFX 2 中初始化 JavaFX 运行时系统以便您可以使用它的唯一方法。

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

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

JavaFX 是单线程系统

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

  1. 当您收到图表的传入请求时,发出Platform.runLater 命令。 runLater 块中的所有代码都将放置在一个队列中,该队列最终将在 JavaFX 应用程序线程上运行。
  2. 在 runLater 块中为您的图表创建一个场景并将其快照到图像。 callback version of snapshot 可能是最适合在这里使用的一个,因为它可能不会过多地占用 JavaFX 应用程序线程,尽管它使用起来可能比较棘手。
  3. 使用 SwingFXUtils.fromFXImage 将 JavaFX 映像转换为 AWT 映像。
  4. 要将图像结果返回到服务器处理程序线程中,请使用 sarcan 在Return result from javafx platform runlater 中概述的FutureTask 技术。

然后,您的服务器处理程序线程可以使用ImageIO 将 AWT 图像转换为 png 等格式的输出流。您可以获取结果流和Base64 encode it,并让服务器返回 base 64 编码流以响应原始图像请求调用。

确保正常关机

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

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

Swing 应用程序可以run in headless mode 使用系统属性java.awt.headless。我不知道 JavaFX 有类似的属性,但可能有,如果有,您可以通过询问 openjfx-dev mailing list 来了解它是什么。

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

您可以在JavaFX issue tracker 中提出官方支持无头模式的请求。

【讨论】:

  • 我认为 JFXPanel 会解决我的问题。但我认为最好从服务器端启动一个新线程并执行 Java FX 逻辑。谢谢你..
  • 我编辑了我的答案以提供额外的实施建议。
  • 当我尝试使用 JFXPanel 实现这一点时,我也遇到了所有这些问题。特别是线程处理。对于无头服务器问题,我在 stackoverflow.com/questions/17940329/… 这个上找到了答案。但我还没有尝试过。谢谢这么详细的回答
猜你喜欢
  • 1970-01-01
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2015-07-31
  • 1970-01-01
  • 2014-07-24
  • 2018-09-06
相关资源
最近更新 更多