How to output the content of a Scene
graph in JavaFX 2 to an Image
. Actually, I am working on an app, which basically designs cards. So, the user just clicks to the various options to customize the scene. Finally I would like to export the scene content to an Image file. How do I do that ?
问题:
回答1:
In FX 2.2 new snapshot feature appeared for that matter. You can just say
WritableImage snapshot = scene.snapshot(null);
With older FX you can use AWT Robot. This is not very good approach as it requires whole AWT stack to start.
// getting screen coordinates of a node (or whole scene)
Bounds b = node.getBoundsInParent();
int x = (int)Math.round(primaryStage.getX() + scene.getX() + b.getMinX());
int y = (int)Math.round(primaryStage.getY() + scene.getY() + b.getMinY());
int w = (int)Math.round(b.getWidth());
int h = (int)Math.round(b.getHeight());
// using ATW robot to get image
java.awt.Robot robot = new java.awt.Robot();
java.awt.image.BufferedImage bi = robot.createScreenCapture(new java.awt.Rectangle(x, y, w, h));
// convert BufferedImage to javafx.scene.image.Image
java.io.ByteArrayOutputStream stream = new java.io.ByteArrayOutputStream();
// or you can write directly to file instead
ImageIO.write(bi, "png", stream);
Image image = new Image(new java.io.ByteArrayInputStream(stream.toByteArray()), w, h, true, true);
回答2:
Update
JavaFX 2.2 (jdk7u6) added a Node snapshot to image feature which would be the preferred way of accomplishing this task.
Prior to 2.2, JavaFX currently does not have a public function to convert a Node or Scene to an Image. There is an open feature request for this http://javafx-jira.kenai.com/browse/RT-13751 (anybody can sign up to view the current feature request status).
As a workaround in the meantime, you could use Swing/AWT functions to convert the JavaFX scene to an image and write the resultant image to a file:
BufferedImage img = new Robot().createScreenCapture(
new java.awt.Rectangle(
(int)sceneRect.getX(), (int)sceneRect.getY(),
(int)sceneRect.getWidth()-1, (int)sceneRect.getHeight()-1));
File file = File.createTempFile("card", ".jpg");
ImageIO.write(img, "jpg", file);
The above code is paraphrased from: JavaFXDev: Screen capture tool.
The sceneRect can be determined by:
Stage stage = (Stage) scene.getWindow();
stage.toFront();
Rectangle sceneRect = new Rectangle(
stage.getX() + scene.getX(), stage.getY() + scene.getY(),
scene.getWidth(), scene.getHeight());
If you follow the above idiom, be careful of threading - such that code accessing the live JavaFX scene only runs on the JavaFX Application Thread and the AWT code only runs on the AWT thread.