【问题标题】:Complete JFXPanel to image完成 JFXPanel 到图像
【发布时间】:2016-04-16 06:28:19
【问题描述】:

我想拍摄一个没有任何视频的网站的快照,所以它只是带有一些 css 和图片的纯文本。

我正在使用 WebView(这是 JFXPanel 的场景)来加载网站,然后通过

WritableImage image = scene.snapshot(new WritableImage(1920, 1080));
BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null);
ImageIO.write(bufferedImage, "png", file);

(其中“场景”是 JFXPanel 的场景)

但保存的图像仅显示网站的一部分,而不是完整的内容(见图)。

如何确保/强制图像的尺寸与 JFXPanel 内容的尺寸相匹配并且一切都可见?

完整代码:

package renderer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.embed.swing.JFXPanel;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.image.WritableImage;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class HtmlRenderer extends Application {
    private JFXPanel jfxPanel;
    private WebView webView;

    public void start(Stage stage) {
        jfxPanel = new JFXPanel();
        webView = new WebView();

        webView.getEngine().getLoadWorker().stateProperty().addListener(
                new ChangeListener<Worker.State>() {
                    @Override
                    public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
                        if (newState == Worker.State.SUCCEEDED) {
                            HtmlRenderer.this.toImage(jfxPanel.getScene());
                            try {
                                Platform.exit();
                                HtmlRenderer.this.stop();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                });

        jfxPanel.setScene(new Scene(webView));

        this.updateView("http://www.stackoverflow.com/");
    }

    private void toImage(Scene scene) {
        WritableImage image = scene.snapshot(new WritableImage(1920, 1080));

        // TODO: save in matching dir using proper filename
        File file = new File("D:/workspace/SiteChecker/test.png");

        try {
            BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null);
            ImageIO.write(bufferedImage, "png", file);
        } catch (IOException e) {
            // TODO: exception handling
        }
    }

    public void updateView(String url) {
        webView.getEngine().load(url);
    }

    private void reloadView() {
        webView.getEngine().reload();
    }

}

【问题讨论】:

  • 上述代码原样导致 Java 8 出现空白页(OpenJDK 和 Oracle 都试过)。
  • @DarrellTeague 你看到接受的答案了吗?我也在使用 Java 8,但只使用了 Oracle。

标签: java html image javafx graphics


【解决方案1】:

所以我找到了一个解决方案,但它远非完美,也不是真正的高性能。 但是,没有其他东西对我有用。 诀窍是加载网站一次,确定网站的宽度和高度。第二次我将 Webview 的首选大小设置为确定的值,并使用新大小再次加载网站。我认为这是因为第一次只渲染了可见部分。

宽度和高度可以用javascript确定,例如:

private int getPageWidth(WebView webView) {
    String script = "Math.max(" +
            "document.body.scrollWidth, document.body.offsetWidth," +
            "document.documentElement.clientWidth, document.documentElement.scrollWidth," +
            "document.documentElement.offsetWidth );";

    WebEngine engine = webView.getEngine();

    int maxWidth = (int) engine.executeScript(script);
    return maxWidth;
}

出于某种原因,某些网站的结尾/底部很有趣,即有很多空白空间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多