Javafx图像到PDF的转换,使用PDFBox显示一半图像

时间:2018-10-14 09:02:15

标签: java javafx pdfbox

我已成功将图像转换为Pdf。我的问题是pdf显示宽度的一半 我的代码:

@FXML
private void print() {
    try {
        WritableImage nodeshot = stackPane.snapshot(new SnapshotParameters(), null);
        File file = new File("C:/Users/Andre Kelvin/Desktop/TheNode.png");
        ImageIO.write(SwingFXUtils.fromFXImage(nodeshot, null), "png", file);

        PDDocument doc = new PDDocument();
        PDPage page = new PDPage();
        PDImageXObject pdimage;
        PDPageContentStream content;

        pdimage = PDImageXObject.createFromFile("C:/Users/Andre Kelvin/Desktop/TheNode.png", doc);
        content = new PDPageContentStream(doc, page);
        content.drawImage(pdimage, 0, 0);
        content.close();
        doc.addPage(page);
        doc.save("C:/Users/Andre Kelvin/Desktop/PDFNode.pdf");
        doc.close();
        file.delete();

        //This Line Automatically Opens the user defualt pdf file viewer
        Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + "C:/Users/Andre Kelvin/Desktop/PDFNode.pdf");
    } catch (Exception e) {
    }
}

我尝试使用此行来获取根节点的宽度和高度:

content.drawImage(pdimage, 0, 0,(float)stackPane.getPrefWidth(),(float)stackPane.getPrefHeight());

这:

content.drawImage(pdimage, 0, 0,(float)stackPane.getMaxWidth(),(float)stackPane.getMaxHeight());

它只会显示空白的页面。

这是转换为pdf的实际图像: enter image description here

这是图像的pdf: enter image description here

1 个答案:

答案 0 :(得分:1)

首选大小属性或与之对应的最小/最大大小均无法可靠地确定Region的大小。这些只是指标,计算出的值可能不匹配。此外,Region的大小可以调整为首选大小以外的其他大小。最后但并非最不重要的一点是,这些属性可能包含特殊值Region.USE_PREF_SIZE(= Double.NEGATIVE_INFINITY)和Region.USE_COMPUTED_SIZE(= -1),甚至默认情况下也是如此。

如果需要获取节点的大小,请使用boundsInLocal属性:

Bounds bounds = stackPane.getBoundsInLocal();

在这种情况下,获取快照的大小更简单。

此外,PDPage的页面大小可能不足以容纳整个图像。您需要缩放图像或更改PDPage的页面大小。


Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + "C:/Users/Andre Kelvin/Desktop/PDFNode.pdf");

这可以通过使用HostServices available via the Application instance与平台无关来完成。

示例

@Override
public void start(Stage primaryStage) {
    Button button = new Button("print");
    StackPane root = new StackPane(button);
    button.setOnAction(evt -> {
        try {
            WritableImage nodeshot = root.snapshot(new SnapshotParameters(), null);

            // store image in-memory
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            ImageIO.write(SwingFXUtils.fromFXImage(nodeshot, null), "png", output);
            output.close();

            PDDocument doc = new PDDocument();
            PDPage page = new PDPage();
            PDImageXObject pdimage;
            PDPageContentStream content;

            pdimage = PDImageXObject.createFromByteArray(doc, output.toByteArray(), "png");
            content = new PDPageContentStream(doc, page);

            // fit image to media box of page
            PDRectangle box = page.getMediaBox();
            double factor = Math.min(box.getWidth() / nodeshot.getWidth(), box.getHeight() / nodeshot.getHeight());

            float height = (float) (nodeshot.getHeight() * factor);

            // beware of inverted y axis here
            content.drawImage(pdimage, 0, box.getHeight() - height, (float) (nodeshot.getWidth() * factor), height);

            content.close();
            doc.addPage(page);

            File outputFile = new File("C:/Users/Andre Kelvin/Desktop/PDFNode.pdf");

            doc.save(outputFile);
            doc.close();

            getHostServices().showDocument(outputFile.toURI().toString());
        } catch (Exception e) {
        }
    });

    Scene scene = new Scene(root, 300, 300);

    primaryStage.setScene(scene);
    primaryStage.show();
}