Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 完成JFXPanel到图像的转换_Java_Html_Image_Javafx_Graphics - Fatal编程技术网

Java 完成JFXPanel到图像的转换

Java 完成JFXPanel到图像的转换,java,html,image,javafx,graphics,Java,Html,Image,Javafx,Graphics,我想拍一个没有任何视频的网站快照,所以它只是一些css和图片的纯文本 我正在使用WebView(JFXPanel的场景)加载网站,然后通过 WritableImage image = scene.snapshot(new WritableImage(1920, 1080)); BufferedImage bufferedImage = SwingFXUtils.fromFXImage(image, null); ImageIO.write(bufferedImage, "png", file);

我想拍一个没有任何视频的网站快照,所以它只是一些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();
    }

}
包渲染器;
导入javafx.application.application;
导入javafx.application.Platform;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.concurrent.Worker;
导入javafx.embed.swing.JFXPanel;
导入javafx.embed.swing.SwingFXUtils;
导入javafx.scene.scene;
导入javafx.scene.image.WritableImage;
导入javafx.scene.web.WebView;
导入javafx.stage.stage;
导入javax.imageio.imageio;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入java.util.List;
公共类HtmlRenderer扩展了应用程序{
私人JFXPanel JFXPanel;
私有网络视图;
公众假期开始(阶段){
jfxPanel=新的jfxPanel();
webView=新建webView();
webView.getEngine().getLoadWorker().stateProperty().addListener(
新的ChangeListener(){
@凌驾
公共无效已更改(observeValue ov,Worker.State oldState,Worker.State newState){
if(newState==Worker.State.successed){
HtmlRenderer.this.toImage(jfxPanel.getScene());
试一试{
Platform.exit();
HtmlRenderer.this.stop();
}捕获(例外e){
e、 printStackTrace();
}
}
}
});
jfxPanel.setScene(新场景(webView));
此.updateView(“http://www.stackoverflow.com/");
}
私人图像(场景){
WritableImage=scene.snapshot(新的WritableImage(19201080));
//TODO:使用正确的文件名保存在匹配目录中
File File=新文件(“D:/workspace/SiteChecker/test.png”);
试一试{
BuffereImage BuffereImage=SwingFXUtils.fromFXImage(图像,null);
write(bufferedImage,“png”,文件);
}捕获(IOE异常){
//TODO:异常处理
}
}
公共无效更新视图(字符串url){
webView.getEngine().load(url);
}
私有void重载视图(){
webView.getEngine().reload();
}
}

所以我找到了一个解决方案,但它还远远不够完美,也没有真正发挥作用。 然而,其他的都不适合我。 诀窍是加载一次网站,确定网站的宽度和高度。第二次,我将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;
}

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

上述代码完全一样,在Java 8上生成一个空白的白色页面(OpenJDK和Oracle都尝试过)。@Darrelltague您看到接受的答案了吗?我也在使用Java8,但只使用Oracle。