【问题标题】:Convert node elements to image将节点元素转换为图像
【发布时间】:2018-10-25 08:22:48
【问题描述】:

我正在寻找可以帮助我将 HTML DOM 节点元素转换为图像/png 文件的库或代码 sn-p。

我尝试使用html2canvas 库,但它不渲染svg 节点,并且在我当前的项目中我有很多。我还尝试使用 canvg 库将页面上的所有 SVG 元素转换为 Canvas 元素,但 canvg 总是在渲染步骤中抛出错误:

Uncaught (in promise) TypeError: Cannot read property 'ImageClass' of 未定义

用于将 SVG 转换为 Canvas 的代码 sn-p:

export const svgToCanvas = () => {
  const print = document.getElementsByClassName('print-page')[0]
  const svgElements = print.getElementsByTagName('svg')
  _.each(svgElements, e => {
    let xml
    const canvas = document.createElement('canvas')
    canvas.className = 'screenShotTempCanvas'
    xml = (new window.XMLSerializer()).serializeToString(e)
    xml = xml.replace(/xmlns=http:\/\/www\.w3\.org\/2000\/svg/, '')
    canvg(canvas, xml)
    e.parentNode.insertBefore(canvas, e.nextSibling)
    e.classList.add('tempHide')
    e.style.display = 'none'
  })

  const temps = document.getElementsByClassName('.screenShotTempCanvas')
  _.each(temps, e => {
    e.remove()
  })
  const svgs = document.getElementsByClassName('tempHide')
  _.each(svgs, e => {
    if (e) {
      e.style.display = 'block'
      e.classList.remove('tempHide')
    }
  })
}

canvg 代码的这一行抛出错误:

if (nodeEnv) {
    if (!s || s === '') {
        return;
    }
    ImageClass = opts['ImageClass'];  //<= error throws here
    CanvasClass = target.constructor;
    svg.loadXml(target.getContext('2d'), s);
    return;
}

我还尝试使用 jsPDFhtml-pdf 库将节点转换为 PDF 格式,但在这种情况下,所有样式都会从节点中消失,我需要它们不要丢失。

谁能提供适当的方法来将 HTML DOM 节点(富含 SVG 元素)转换为图像?

【问题讨论】:

    标签: javascript html svg canvas html2canvas


    【解决方案1】:

    这似乎是 canvg 作者严重错误测试和记录的结果。引发错误的行是作为pull request 的一部分引入的,据称它增加了对在节点环境中执行canvg 的支持。但它似乎只有在 node-svg2img 中用作依赖项时才经过测试。

    如果您查看该来源,您会发现以下内容(摘录):

    var canvg = require('canvg'),
        Canvas = require('canvas');
    
    function convert(svgContent) {
        var canvas = new Canvas();
        canvg(canvas, svgContent, { ignoreMouse: true, ignoreAnimation: true, ImageClass: Canvas.Image });
        return canvas;
    }
    

    如您所见,canvg 使用从未被记录的选项ImageClass 调用,其内容依赖于模块canvas,该模块从未被声明为canvg 的依赖项。 (这不是轻量级的,它是完整的&lt;canvas&gt; 实现。)

    现在你从来没有说过你在 node 中做所有这些,但我会假设你这样做,否则我不明白为什么会调用导致错误的行。

    似乎对document.createElement('canvas') 的成功调用并不表示您已安装canvas 模块。 jsdom 文档中的This note 告诉您需要做什么。

    从那里,在你的代码中调用canvg

    import Image from 'canvas';
    
    canvg(canvas, xml, {ImageClass: Image});
    

    应该让你跑起来。

    【讨论】:

    • 感谢您的回答,它真的很有用。 canvg 库现在可以正常工作,没有任何错误。但它效果不佳,并将 svg 元素转换为带有扭曲的画布。您能否建议任何其他库将 svg 转换为画布,或另一种将节点元素导出为图像的方法?
    • 我不知道是否还有其他库,但是如果您使用PhantomJS,您将拥有一个完整的无头浏览器,您可以在其中运行本机画布API而无需canvg。
    猜你喜欢
    • 2015-05-03
    • 1970-01-01
    • 2014-05-13
    • 2010-11-04
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    相关资源
    最近更新 更多