是否有一种方法将html渲染成PNG那样的图像?我知道这是可能的与画布,但我想渲染标准的html元素,如div为例。


当前回答

我读了Sjeiti的答案,我觉得很有趣,在那里你只需要几行简单的JavaScript就可以在图像中呈现HTML。

当然,我们必须意识到这种方法的局限性(请在他的回答中阅读其中的一些)。

在这里,我进一步使用了他的代码。

svg图像原则上具有无限分辨率,因为它是矢量图形。但您可能已经注意到,Sjeiti的代码生成的图像分辨率并不高。在将SVG-image转移到canvas-element之前,可以通过缩放SVG-image来解决这个问题,我在下面给出的两个(可运行的)示例代码中的最后一个代码中已经做到了这一点。我在该代码中实现的另一件事是最后一步,即将其保存为png文件。只是为了完成整个过程。

因此,我给出了两个可运行的代码片段:

第一个演示了SVG的无限分辨率。运行它并使用浏览器放大,以查看分辨率是否随着放大而减小。

在您可以运行的代码片段中,我已经使用反勾号指定了一个带有换行符的所谓模板字符串,以便您可以更清楚地看到呈现的HTML。但是,如果HTML在一行之内,那么代码就会非常短,就像这样。

const body = document.getElementsByTagName('BODY')[0];
const img = document.createElement('img')
img.src = 'data:image/svg+xml,' + encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml" style="border:1px solid red;padding:20px;"><style>em {color:red;}.test {color:blue;}</style>What you see here is only an image, nothing else.<br /><br /><em>I</em> really like <span class="test">cheese.</span><br /><br />Zoom in to check the resolution!</div></foreignObject></svg>`);        
body.appendChild(img);

这里是一个可运行的代码片段。

const body = document.getElementsByTagName('BODY')[0]; const img = document.createElement('img') img.src = 'data:image/svg+xml,' + encodeURIComponent(` <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"> <foreignObject width="100%" height="100%"> <div xmlns="http://www.w3.org/1999/xhtml" style="border:1px solid red;padding:20px;"> <style> em { color:red; } .test { color:blue; } </style> What you see here is only an image, nothing else.<br /> <br /> <em>I</em> really like <span class="test">cheese.</span><br /> <br /> Zoom in to check the resolution! </div> </foreignObject> </svg> `); body.appendChild(img);

放大并检查SVG的无限分辨率。

下面的下一个可运行文件实现了我上面提到的两个额外步骤,即通过缩放SVG来提高分辨率,然后将其保存为png图像。

window.addEventListener("load", doit, false) var canvas; var ctx; var tempImg; function doit() { const body = document.getElementsByTagName('BODY')[0]; const scale = document.getElementById('scale').value; let trans = document.getElementById('trans').checked; if (trans) { trans = ''; } else { trans = 'background-color:white;'; } let source = ` <div xmlns="http://www.w3.org/1999/xhtml" style="border:1px solid red;padding:20px;${trans}"> <style> em { color:red; } .test { color:blue; } </style> What you see here is only an image, nothing else.<br /> <br /> <em>I</em> really like <span class="test">cheese.</span><br /> <br /> <div style="text-align:center;"> Scaling: <br /> ${scale} times! </div> </div>` document.getElementById('source').innerHTML = source; canvas = document.createElement('canvas'); ctx = canvas.getContext('2d'); canvas.width = 200*scale; canvas.height = 200*scale; tempImg = document.createElement('img'); tempImg.src = 'data:image/svg+xml,' + encodeURIComponent(` <svg xmlns="http://www.w3.org/2000/svg" width="${200*scale}" height="${200*scale}"> <foreignObject style=" width:200px; height:200px; transform:scale(${scale}); " >` + source + ` </foreignObject> </svg> `); } function saveAsPng(){ ctx.drawImage(tempImg, 0, 0); var a = document.createElement('a'); a.href = canvas.toDataURL('image/png'); a.download = 'image.png'; a.click(); } <table border="0"> <tr> <td colspan="2"> The claims in the HTML-text is only true for the image created when you click the button. </td> </tr> <tr> <td width="250"> <div id="source" style="width:200px;height:200px;"> </div> </td> <td valign="top"> <div> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;In this example the PNG-image will be squarish even if the HTML here on the left is not exactly squarish. That can be fixed.<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;To increase the resolution of the image you can change the scaling with this slider. <div style="text-align:right;margin:5px 0px;"> <label style="background-color:#FDD;border:1px solid #F77;padding:0px 10px;"><input id="trans" type="checkbox" onchange="doit();" />&nbsp;&nbsp;Make it transparent</label> </div> <span style="white-space:nowrap;">1<input id="scale" type="range" min="1" max="10" step="0.25" value="2" oninput="doit();" style="width:150px;vertical-align:-8px;" />10&nbsp;&nbsp;<button onclick="saveAsPng();">Save as PNG-image</button></span> </div> </td> </tr> </table>

尝试不同的比例。例如,如果您将缩放设置为10,那么您将在生成的png图像中获得非常好的分辨率。我还添加了一个额外的功能:一个复选框,这样你就可以使png图像透明。

注意:

当这个脚本在Stack Overflow运行时,保存按钮在Chrome和Edge中不工作。原因是https://www.chromestatus.com/feature/5706745674465280。

因此,我也把这个片段放在https://jsfiddle.net/7gozdq5v/上,它适用于这些浏览器。

其他回答

我在Chrome、Firefox和MS Edge上使用的唯一一个库是rasterizeHTML。它输出比HTML2Canvas更好的质量,并且仍然受支持,不像HTML2Canvas。

获取元素和下载为PNG

var node= document.getElementById("elementId");
var canvas = document.createElement("canvas");
canvas.height = node.offsetHeight;
canvas.width = node.offsetWidth;
var name = "test.png"

rasterizeHTML.drawHTML(node.outerHTML, canvas)
     .then(function (renderResult) {
            if (navigator.msSaveBlob) {
                window.navigator.msSaveBlob(canvas.msToBlob(), name);
            } else {
                const a = document.createElement("a");
                document.body.appendChild(a);
                a.style = "display: none";
                a.href = canvas.toDataURL();
                a.download = name;
                a.click();
                document.body.removeChild(a);
            }
     });

你可以添加引用HtmlRenderer到你的项目,并执行以下操作:

string htmlCode ="<p>This is a sample html.</p>";
Image image = HtmlRender.RenderToImage(htmlCode ,new Size(500,300));

使用html2canvas只包括插件和调用方法,将HTML转换为画布,然后下载为PNG图像

        html2canvas(document.getElementById("image-wrap")).then(function(canvas) {
            var link = document.createElement("a");
            document.body.appendChild(link);
            link.download = "manpower_efficiency.jpg";
            link.href = canvas.toDataURL();
            link.target = '_blank';
            link.click();
        });

来源:http://www.freakyjolly.com/convert-html-document-into-image-jpg-png-from-canvas/

这就是我所做的。

注意:请检查App.js的代码。

链接到源代码

如果你喜欢它,你可以掉一颗星。✌️

更新:

import * as htmlToImage from 'html-to-image';
import download from 'downloadjs';

import logo from './logo.svg';
import './App.css';

const App = () => {
  const onButtonClick = () => {
    var domElement = document.getElementById('my-node');
    htmlToImage.toJpeg(domElement)
      .then(function (dataUrl) {
        console.log(dataUrl);
        download(dataUrl, 'image.jpeg');
      })
      .catch(function (error) {
        console.error('oops, something went wrong!', error);
      });
  };
  return (
    <div className="App" id="my-node">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a><br></br>
        <button onClick={onButtonClick}>Download as JPEG</button>
      </header>
    </div>
  );
}

export default App;

安装幻影

$ npm install phantomjs

用以下代码创建一个文件github.js

var page = require('webpage').create();
//viewportSize being the actual size of the headless browser
page.viewportSize = { width: 1024, height: 768 };
page.open('http://github.com/', function() {
    page.render('github.png');
    phantom.exit();
});

将文件作为参数传递给phantomjs

$ phantomjs github.js