使用 HTML5 画布和 SVG 从 DOM 节点生成图像。
从 dom 到 image 的 fork 具有更易于维护的代码和一些新功能。
npm install --save html-to-image
/* ES6 */import * as htmlToImage from 'html-to-image';import { toPng, toJpeg, toBlob, toPixelData, toSvg } from 'html-to-image';/* ES5 */var htmlToImage = require(' html 到图像');
所有顶级函数都接受 DOM 节点和渲染选项,并返回一个用相应的 dataURL 履行的承诺:
到Svg
转Png
转Jpeg
到Blob
到像素数据
请看以下示例。
获取 PNG 图像 base64 编码的数据 URL 并立即显示它:
var node = document.getElementById('my-node');htmlToImage.toPng(node) .then(function (dataUrl) {var img = new Image();img.src = dataUrl;document.body.appendChild(img); }) .catch(function (error) {console.error('哎呀,出了问题!', error); });
获取 PNG 图像 base64 编码的数据 URL 并下载它(使用 download):
htmlToImage.toPng(document.getElementById('my-node')) .then(function (dataUrl) {download(dataUrl, 'my-node.png'); });
获取 PNG 图像 blob 并下载它(使用 FileSaver):
htmlToImage.toBlob(document.getElementById('my-node')) .then(function (blob) {window.saveAs(blob, 'my-node.png'); });
保存并下载压缩的 JPEG 图像:
htmlToImage.toJpeg(document.getElementById('my-node'), { 质量: 0.95 }) .then(function (dataUrl) {var link = document.createElement('a');link.download = 'my-image-name.jpeg';link.href = dataUrl;link.click(); });
获取 SVG 数据 URL,但过滤掉所有<i>
元素:
函数过滤器(节点){ return (node.tagName !== 'i');}htmlToImage.toSvg(document.getElementById('my-node'), { filter: 过滤器 }) .then(function (dataUrl) {/* 做某事 */ });
获取 Uint8Array 形式的原始像素数据,其中每 4 个数组元素代表像素的 RGBA 数据:
var node = document.getElementById('my-node');htmlToImage.toPixelData(node) .then(函数(像素) {for (var y = 0; y < node.scrollHeight; ++y) { for (var x = 0; x < node.scrollWidth; ++x) {pixelAtXYOffset = (4 * y) * node.scrollHeight) + (4 * x);/* PixelAtXY 是一个 Uint8Array[4],包含范围内 (x, y) 处像素的 RGBA 值0..255 */pixelAtXY = Pixels.slice(pixelAtXYOffset, PixelAtXYOffset + 4); });
获取一个 HTMLCanvasElement,并立即显示它:
htmlToImage.toCanvas(document.getElementById('my-node')) .then(function (canvas) {document.body.appendChild(canvas); });
以 DOM 节点作为参数的函数。如果传递的节点应包含在输出中,则应返回 true。排除节点意味着也排除它的子节点。
不在根节点上调用。
背景颜色的字符串值,任何有效的 CSS 颜色值。
在渲染之前应用于节点的宽度和高度(以像素为单位)。
在渲染之前将其属性复制到节点样式的对象。您可能需要检查此参考以获取 CSS 属性的 JavaScript 名称。
0
到1
之间的数字,表示 JPEG 图像的图像质量(例如0.92
=> 92%
)。
默认为1.0
( 100%
)
设置为 true 可将当前时间作为查询字符串附加到 URL 请求以启用缓存清除。
默认为false
获取图像失败时将使用的占位符图像的数据 URL。
默认为空字符串,将为失败的图像渲染空白区域。
它在最新的 Chrome 和 Firefox(撰写本文时分别为 49 和 45)上进行了测试,Chrome 在大型 DOM 树上的性能明显更好,这可能是因为它具有更高性能的 SVG 支持,并且它支持CSSStyleDeclaration.cssText
属性。
Internet Explorer 不受(也不会受)支持,因为它不支持 SVG <foreignObject>
标记。
Safari 不受支持,因为它在<foreignObject>
标记上使用更严格的安全模型。建议的解决方法是使用toSvg
并在服务器上渲染。
当前仅使用标准库,但请确保您的浏览器支持:
承诺
SVG <foreignObject>
标签
可能有一天存在(或者可能已经存在?)一种将 HTML 部分导出到图像的简单而标准的方法(然后这个脚本只能作为我必须跳过的所有障碍的证据才能获得这样的结果)显然已经完成了)但到目前为止我还没有找到。
该库使用 SVG 的一项功能,允许在<foreignObject>
标记内包含任意 HTML 内容。因此,为了为您渲染 DOM 节点,需要执行以下步骤:
递归克隆原始 DOM 节点
计算节点和每个子节点的样式并将其复制到相应的克隆
并且不要忘记重新创建伪元素,因为它们当然不会以任何方式克隆
嵌入网络字体
查找所有可能代表网络字体的@font-face
声明
解析文件URL,下载对应文件
Base64 编码和内联内容作为 dataURL
连接所有已处理的 CSS 规则并将它们放入一个<style>
元素中,然后将其附加到克隆
嵌入图像
在<img>
元素中嵌入图像 URL
background
CSS 属性中使用的内联图像,其方式类似于字体
将克隆的节点序列化为 XML
将 XML 包装到<foreignObject>
标签中,然后包装到 SVG 中,然后将其设为数据 URL
或者,要获取 Uint8Array 形式的 PNG 内容或原始像素数据,请创建一个以 SVG 作为源的 Image 元素,并将其渲染在您也创建的离屏画布上,然后从画布中读取内容
完毕!
如果要渲染的 DOM 节点包含一个<canvas>
元素,并且在其上绘制了一些内容,则应该很好地处理它,除非画布被污染 - 在这种情况下渲染将不会成功。
由于 dataURI 限制不同,在巨大 DOM 上渲染将失败。
非常欢迎拉取请求和星星。
对于错误和功能请求,请创建问题。