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


当前回答

使用这段代码,它一定会工作:

<脚本type = " text / javascript”> 美元(文档)。Ready (function () { setTimeout(函数(){ downloadImage (); }, 1000) }); 函数downloadImage () { html2canvas (document.querySelector(“# dvContainer”))。然后(canvas => { a = document.createElement('a'); document.body.appendChild(一个); A.download = "test.png"; a.href = canvas.toDataURL(); a.click (); }); } > < /脚本

不要忘记在你的程序中包含Html2CanvasJS文件。 https://html2canvas.hertzen.com/dist/html2canvas.js

其他回答

请允许我推荐dom-to-image库,这是专门用来解决这个问题的(我是维护者)。 下面是你如何使用它(更多):

var node = document.getElementById('my-node');

domtoimage.toPng(node)
    .then (function (dataUrl) {
        var img = new Image();
        img.src = dataUrl;
        document.appendChild(img);
    })
    .catch(function (error) {
        console.error('oops, something went wrong!', error);
    });

你可以使用PhantomJS,这是一个无头webkit (safari和chrome(直到最近)的渲染引擎)驱动程序。您可以在这里学习如何对页面进行屏幕捕获。希望有帮助!

有很多选择,它们都有各自的优点和缺点。

选项1:使用API

ApiFlash(基于chrome) EvoPDF(有html选项) Grabzit HTML/CSS图像API ...

Pros

执行Javascript 近乎完美渲染 正确使用缓存选项时快速 缩放由api处理 精确计时,视口,… 大多数时候,他们提供的是免费方案

Cons

如果你打算经常使用它们,就不是免费的

选项2:使用众多可用库中的一个

dom-to-image Wkhtmltoimage(包含在wkhtmltopdf工具中) IMGKit(用于ruby和基于wkhtmltoimage) Imgkit(适用于python,基于wkhtmltoimage) python-webkit2png ...

Pros

大多数时候,转换是相当快的

Cons

坏的呈现 不执行javascript 不支持最近的网页功能(FlexBox,高级选择器,网页字体,盒子大小,媒体查询,…) 有时不容易安装 缩放复杂

选项3:使用PhantomJs和包装器库

PhantomJs node-webshot(用于PhantomJs的javascript包装库) ...

Pros

执行Javascript 很快

Cons

坏的呈现 不支持最近的网页功能(FlexBox,高级选择器,网页字体,盒子大小,媒体查询,…) 缩放复杂 不那么容易使它工作,如果有图像要加载…

选项4:使用Chrome Headless和一个包装器库

Chrome无头 chrome-devtools-protocol Puppeteer (Chrome无头浏览器的javascript包装库) ...

Pros

执行Javascript 近乎完美渲染

Cons

要得到想要的结果并不容易: 页面加载时间 视窗尺寸 缩放复杂 相当慢,甚至更慢,如果html包含外部链接

披露:我是ApiFlash的创始人。我尽力提供了一个诚实而有用的答案。

安装幻影

$ 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

这里所有的答案都使用第三方库,而在纯Javascript中将HTML渲染为图像可以相对简单。在MDN的画布部分甚至有一篇关于它的文章。

诀窍是这样的:

使用包含XHTML的foreignObject节点创建SVG 将图像的src设置为该SVG的数据url 将图像绘制到画布上 将画布数据设置为目标image.src

const {body} = document const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') canvas.width = canvas.height = 100 const tempImg = document.createElement('img') tempImg.addEventListener('load', onTempImageLoad) tempImg.src = 'data:image/svg+xml,' + encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml"><style>em{color:red;}</style><em>I</em> lick <span>cheese</span></div></foreignObject></svg>') const targetImg = document.createElement('img') body.appendChild(targetImg) function onTempImageLoad(e){ ctx.drawImage(e.target, 0, 0) targetImg.src = canvas.toDataURL() }

需要注意的一些事情

The HTML inside the SVG has to be XHTML For security reasons the SVG as data url of an image acts as an isolated CSS scope for the HTML since no external sources can be loaded. So a Google font for instance has to be inlined using a tool like this one. Even when the HTML inside the SVG exceeds the size of the image it wil draw onto the canvas correctly. But the actual height cannot be measured from that image. A fixed height solution will work just fine but dynamic height will require a bit more work. The best is to render the SVG data into an iframe (for isolated CSS scope) and use the resulting size for the canvas.