换句话说,我正在尝试像Java Batik allows you to do with Swing.
那样使用JavaFX我希望能够在我的JavaFX UI中捕获任意节点的外观,就像Node.snapshot()一样,除了我需要像SVG这样的矢量格式的图像,而不是光栅图像。 (并且将我的节点的光栅快照插入到SVG图像中是不够的;它需要是一个适当的,可缩放的矢量图像。)
这是一个长期项目,所以我甚至愿意实现我自己的GraphicsContext,或者JavaFX的保留模式API中的等价物。
有没有人知道是否有办法做到这一点?我希望在JavaFX中甚至可以做什么?
答案 0 :(得分:5)
我开始编写一个JavaFx节点到SVG转换器,"扩展" Gerrit Grunwald的ShapeConverter只转换Shape几何形状:
https://github.com/stefaneidelloth/JavaFxNodeToSvg
......并在一定程度的挫败之后停止了它。
请随时改进,添加功能并修复错误。
转换器适用于简单的Node示例,但对于图表等高级示例则失败。我失败的转换器可能会为您提供一个起点。下面的图说明了当前的状态。左侧显示原始JavaFx节点,右侧显示结果svg输出。
这里有相应的svg文件:
https://github.com/stefaneidelloth/JavaFxNodeToSvg/tree/master/output
进一步说明
除了上面的图表示例所示的定位问题之外,还需要考虑其他一些问题:
JavaFx提供比SVG标准元素更多的css功能。例如,(矩形)JavaFx区域可以为四条边界线中的每一条具有单独的线条样式。这样的区域不能简单地转换为SVG矩形。相反,需要单独绘制区域的四条边界线。此外,这种边界线的每个末端可以具有两个单独的边缘半径:垂直半径和水平半径。为了转换"四"边界线到相应的SVG线......可能需要进一步分割边界线:为四条边界线中的每一条绘制两个圆角部分和一个直线部分。因此,在某些情况下,可能有12个SVG路径元素来绘制单个JavaFx区域的边框。此外,Region的背景填充可以具有与Region的边界不同的半径。绘制Region的背景可能需要更多的SVG元素。因此,即使转换了矩形区域"会变得相当复杂。
请注意,JavaFx节点可能已设置动画。例如,行的不透明度在开始时为0,在几毫秒后逐渐消失为另一个值。
FadeTransition ft = new FadeTransition(Duration.millis(250), borderline);
ft.setToValue(0);
ft.play();
因此,仅转换禁用动画的节点或等待节点处于稳定状态才有意义。
如果JavaFx图表的转换工作一天,我会非常高兴,因此我可以在我的一个项目中使用JavaFx绘图和SVG导出。
我决定暂时停止转换器的开发,并使用JavaScript库(d3)调查绘图和SVG导出。如果该策略更糟糕,我可能会回到JavaFxNodeToSvgConverter。
修改强> 使用d3.js进行绘图非常有效,我决定不使用JavaFx来绘制/ svg创建。 https://github.com/stefaneidelloth/javafx-d3
答案 1 :(得分:1)
有一个简单的JavaFX shape to SVG string converter,它只会在没有应用css的情况下转换基本形状,而不是任意节点,但也许这可能只是你需要的。
答案 2 :(得分:1)
JFX JIRA中有一个开放的错误请求
https://javafx-jira.kenai.com/browse/RT-38559
(需要注册;然后您可以投票支持该问题)。它目前说
考虑将来的版本。
并标记为版本9.
答案 3 :(得分:0)
我们的想法是,如果您能够将JavaFX节点树结构转换为一系列Graphics2D订单,那么您可以使用具有Graphics2D驱动程序的Batik。
问题在于,将JavaFX树结构转换为Graphics2D顺序并不像您想象的那么困难(即使您处理节点的CSS属性)。
有些读者建议我应该包含一些代码,而不仅仅是图书馆的链接及其工作的图片。这样做并不容易,因为即使它不是那么难做,它仍然有5000行代码。
如何执行转换:
请注意,您不需要支持很多Node类型,主要是:
您可能还需要处理节点剪辑以在Graphics2D中应用关联的剪辑。
此外,您还必须处理Node的CSS属性。
尽管如此,我使用的库(这个算法适用于此算法)在这里:http://sourceforge.net/projects/jfxconverter/