下载由JavaScript返回的图像(HTML2Canvas)



我正在尝试从网页下载图像,该网页由JavaScript(使用HTML2Canvas)返回,然后在调用它后立即返回。因此,我正在使用库htmlunit,但直到现在我还没有成功。

不幸的是,只有一个错误的png文件下载,约为140kb。它不能由Windows打开(例如油漆或预览)。

我的html-page代码 - nippet(加载div-Element #div后立即执行:

function saveMap() {
    var element = $("#div");
    html2canvas(element, {
        useCORS: true,
        onrendered: function(canvas) {
            var dataUrl= canvas.toDataURL("image/png");
            var a = $("<a>")
                .attr("href", dataUrl)
                .attr("download", "test.png")
                .appendTo("body");
            a[0].click();
            a.remove();
        }
    });
}

Java代码试图下载返回的png-file:

WebClient webClient = new WebClient(BrowserVersion.CHROME);
try {
    HtmlPage page1 = webClient.getPage( new URI("file:///D:/path/to/page/sample.html").toURL() );
    webClient.waitForBackgroundJavaScript(5000);

    InputStream is = page1.getWebResponse().getContentAsStream();
    File f = new File("test.png");
    OutputStream os = new FileOutputStream(f);
    byte[] bytes = new byte[2048];
    int b = 0;
    while ((b = is.read()) != -1)
    {
        os.write(bytes, 0, b);
    }
    os.close();
    is.close();
} catch (FailingHttpStatusCodeException | IOException | URISyntaxException e) {
    e.printStackTrace();
}

完整的html页:

<!DOCTYPE html>
<html>
    <head>
    <style>
    html, body, #div {
        height: 100%;
        width: 100%;
        margin: 0px;
        padding: 0px
    }
    </style>
    <script src="html2canvas.js"></script>
    <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
    </head>
    <body>
    <div id="div"></div>
        <script>
            // Some init stuff for div and after completion the following:
            saveMap();
        function saveMap() {
            var element = $("#div");
            html2canvas(element, {
                useCORS: true,
                onrendered: function(canvas) {
                    var dataUrl= canvas.toDataURL("image/png");
                    var a = $("<a>")
                        .attr("href", dataUrl)
                        .attr("download", "test.png")
                        .appendTo("body");
                    a[0].click();
                    a.remove();
                }
            });
        }
        </script>
    </body>
</html>

感谢您的代码。已经对HTML2Canvas网页上可用的样本进行了一些测试。当前版本的HTMLUNIT有错误,可以阻止JavaScript工作。我认为我也做了一个修复程序,但是SourceForge目前正在下降。如果他们回来了,我将提交修复程序并准备一个新的快照。会通知您,还可以查看您的样本。

顺便说一句:不要期望从中屏幕截图不错。HTMLUNIT是一个无头浏览器,大多数布局功能仅在做基本工作。但是欢迎您提供更好的实施。

带有最新快照的代码(带有一些修复程序)。但是要获得合理的结果,您必须为结果提供宽度和高度。我猜HTMLUNIT中有一些布局,否则将返回1x1的结果大小。如果这是一个问题,您可能会在代码内部查看并尝试指向有问题的地方。

        html2canvas(element, {
            useCORS: true,
            width: 300,
            height: 300,
            onrendered: function(canvas) {

现在到您的Java代码

HtmlPage page1 = webClient.getPage( new URI("file:///D:/path/to/page/sample.html").toURL() );
webClient.waitForBackgroundJavaScript(5000);

这里棘手的部分是浏览器内部渲染的异步执行。从htmlunit的角度来看,浏览器将在完成页面加载后,用PNG图像替换当前窗口的内容。并且您必须在代码中处理此问题。因为有一个替换,您的页面仍然是返回的旧页面(同步)。等待之后,您必须重新列出当前内容才能将PNG手中掌握

        Page image = webClient.getCurrentWindow().getEnclosedPage();
        InputStream is = image.getWebResponse().getContentAsStream();

最后,您的图像写作代码有一个小问题而不是

while ((b = is.read()) != -1)

你必须写

while ((b = is.read(bytes)) != -1)

否则,您最终将获得一个null字节的文件。

希望会有所帮助。

最新更新