【问题标题】:HTML2Canvas combine 2 captured canvases into oneHTML2Canvas 将 2 个捕获的画布合二为一
【发布时间】:2014-12-11 17:23:52
【问题描述】:

使用 HTML2Canvas 我正在尝试捕获 googleMap(效果很好),然后捕获位于其顶部的 #overlay div(它允许人们将图像放置在googleMap 在特定位置)(工作正常)。

然后页面会在页面上显示这两个canvas 元素,然后我想要另一个捕获这些元素,以将两个画布组合成一个图像,然后他们可以下载。

到目前为止,我遇到的问题是,当我尝试捕获我的 #preview div 时,HTML2Canvas 似乎没有拾取它创建的 canvas 元素。

HTML:

<div id="mainPanel">
    <div id="overlay">

    </div>
    <button class="download">Download as PDF</button>
    <button onclick="startEdit();" class="edit_button">Start Editing</button>
    <div id="map">
        <input id="pac-input" class="controls" type="text" placeholder="Search Box">
        <div id="map-canvas"></div>
    </div>
    <div id="preview">

    </div>
</div>

HTML2Canvas jQuery:

$(".download").click(function() {
        html2canvas($("#map"), {
            logging: true,
            proxy: "https://html2canvas.appspot.com/query",
            onrendered: function(canvas) {
                // var img = canvas.toDataURL("image/png");
                $(canvas).css({"position" : "absolute", "z-index" : "999"});
                document.getElementById("preview").appendChild(canvas);

                html2canvas($("#overlay"), {
                    logging: true,
                    onrendered: function(canvas1) {

                        // var img = canvas.toDataURL("image/png");
                        $(canvas1).css({"position" : "absolute", "z-index" : "1000"});
                        document.getElementById("preview").appendChild(canvas1);

                        setTimeout(function() {downloadURI()}, 5000);
                    }
                });
            }
        });
});

function downloadURI() {
    html2canvas($("#preview"), {
        logging: true,
        onrendered: function(canvas2) {

            var img = canvas2.toDataURL("image/png");
                window.open(img);
                // var link = document.createElement("a");
                // link.download = "image-download.png";
                // link.href = img;
                // link.click();
            }
        });
    }

如您所见,我已尝试延迟 DownloadURI 函数,以防画布未及时加载,但这不是问题。我不确定是否有关于 canvas 元素的某些内容不适用于插件。

工作原理:我上面的代码相当简单。当一个 HTML2Canvas 完成后,它会运行另一个 HTML2Canvas。这两个画布都附加到#preview 元素,以便我可以捕获该元素,其中两个画布在其中相互重叠。完成后,它会运行另一个函数来捕获#preview 元素,我希望将这两个图像一个在另一个之上组合成一个用户可以下载的图像,但是它只是返回一个空图像。

如果需要更多信息,请告诉我,谢谢。

【问题讨论】:

  • 与其创建第三个预览 div,为什么不简单地通过它们的数据合并两个图像呢?如果有可能,我可以用代码提交答案。
  • 我不确定这是否可能。如果你能做到,那就太棒了! :D

标签: javascript jquery html canvas html2canvas


【解决方案1】:

这个函数接受两个参数topbottom。两者都应该是 ImageData 对象,您可以通过ctx.getImageData() 获得。底部的 ImageData 与合并到它的顶部数据一起返回。该函数使用 Porter-Duff 方法来合并颜色。

function mergeData(top, bottom){
    var tD = top.data,
        bD = bottom.data,
        l = tD.length;
    for(var i = 0; i < l; i += 4){
        //source alpha
        var alphaSrc = tD[i+3] / 255, //source alpha
            alphaDst = bD[i+3] / 255, //destination alpha
            alphaSrcO = 1 - alphaSrc, //(1 - x)
            alpha = alphaSrc + alphaDst * alphaSrcO; //if destination alpha is opaque
        //merge colors
        bD[i] = ((tD[i]*alphaSrc) + (bD[i]*alphaDst*alphaSrcO)) / alpha,
        bD[i+1] = ((tD[i+1]*alphaSrc) + (bD[i+1]*alphaDst*alphaSrcO)) / alpha,
        bD[i+2] = ((tD[i+2]*alphaSrc) + (bD[i+2]*alphaDst*alphaSrcO)) / alpha,
        bD[i+3] = 255*alpha;
    }
    //return bottom
    return bottom;
}

要使用此函数并返回数据,请执行以下操作:

var merged = mergeData(ctx1.getImageData(), ctx2.getImageData());
ctx2.putImageData(merged, 0, 0);

显然,如果需要,您可以将结果数据放入第三个隐藏的上下文中。

【讨论】:

  • 那么关于传递给函数的变量,我可以使用注释掉的var img = canvas.toDataURL("image/png");吗?还是我需要在两者上都使用ctx.getImageData();
  • 您需要使用getImageData(),因为toDataURL() 返回一个base64 字符串,而不是您可以使用的对象。
  • 您能解释一下我如何将getImageData 与返回的画布一起使用吗? (我以前没用过,第一次)返回的画布实际上不是一个元素,所以我不知道如何使用它:P
  • Google 东西真的没那么难:/ 你需要使用putImageData
  • 我一直在谷歌上搜索它,但我不知道如何将它与你的函数联系起来。我是否需要为putImageData 设置一个变量,然后将其传递给函数?
猜你喜欢
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-02
  • 1970-01-01
相关资源
最近更新 更多