【问题标题】:Save SVG as PNG using javascript Unknown DOM exception使用 javascript 将 SVG 保存为 PNG 未知 DOM 异常
【发布时间】:2017-11-08 06:14:11
【问题描述】:

我正在尝试使用 javascript 通过浏览器将 SVG 转换为 PNG
我一直在关注这个问题的答案Save inline SVG as JPEG/PNG/SVG

它适用于该答案中的给定 XML 不幸的是,我在尝试转换我的 SVG 时收到了Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.。这是我的代码的 sn-p。谁能告诉我为什么它不起作用?

var btn = document.querySelector('button');
var svg = document.querySelector('svg');
var canvas = document.querySelector('canvas');

function triggerDownload (imgURI) {
  var evt = new MouseEvent('click', {
    view: window,
    bubbles: false,
    cancelable: true
  });

  var a = document.createElement('a');
  a.setAttribute('download', 'MY_COOL_IMAGE.png');
  a.setAttribute('href', imgURI);
  a.setAttribute('target', '_blank');

  a.dispatchEvent(evt);
}

btn.addEventListener('click', function () {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  var data = (new XMLSerializer()).serializeToString(svg);
  var DOMURL = window.URL || window.webkitURL || window;

  var img = new Image();
  img.crossOrigin = 'anonymous'

  var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
  var url = DOMURL.createObjectURL(svgBlob);

  img.onload = function () {
    ctx.drawImage(img, 0, 0);
    DOMURL.revokeObjectURL(url);

    var imgURI = canvas
        .toDataURL('image/png')
        .replace('image/png', 'image/octet-stream');

    triggerDownload(imgURI);
  };

  img.src = url;
});
<button>svg to png</button>

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="161px" height="91px" version="1.1" style="background-color: rgb(255, 255, 255);"><defs/><g transform="translate(0.5,0.5)"><rect x="0" y="0" width="160" height="90" fill="#ffffff" stroke="#000000" pointer-events="none"/><path d="M 0 26 L 0 0 L 160 0 L 160 26 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(48.5,7.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="63" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; white-space: nowrap; font-weight: bold; text-align: center;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">Classname</div></div></foreignObject><text x="32" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica" font-weight="bold">Classname</text></switch></g><g transform="translate(5.5,32.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="62" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; overflow: hidden; max-height: 22px; max-width: 148px; width: 63px; white-space: normal; word-wrap: normal;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">+ field: type</div></div></foreignObject><text x="31" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">+ field: type</text></switch></g><path d="M 0 56 L 160 56" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(5.5,66.5)"><switch><foreignObject style="overflow:visible;" pointer-events="all" width="111" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; overflow: hidden; max-height: 22px; max-width: 148px; width: 112px; white-space: normal; word-wrap: normal;"><div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;">+ method(type): type</div></div></foreignObject><text x="56" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">+ method(type): type</text></switch></g></g></svg>

<canvas id="canvas"></canvas>

【问题讨论】:

  • 为什么需要将svg 转换为png?为什么不能以svg的身份下载使用图片?
  • 这是要求之一,对此无能为力。

标签: javascript jquery svg png


【解决方案1】:

您在 SVG 的 foreignObject 中遇到问题,删除它会解决您的问题,

var btn = document.querySelector('button');
var svg = document.querySelector('svg');
var canvas = document.querySelector('canvas');

function triggerDownload (imgURI) {
  var evt = new MouseEvent('click', {
    view: window,
    bubbles: false,
    cancelable: true
  });

  var a = document.createElement('a');
  a.setAttribute('download', 'MY_COOL_IMAGE.png');
  a.setAttribute('href', imgURI);
  a.setAttribute('target', '_blank');

  a.dispatchEvent(evt);
}

btn.addEventListener('click', function () {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  var data = (new XMLSerializer()).serializeToString(svg);
  var DOMURL = window.URL || window.webkitURL || window;

  var img = new Image();
  img.crossOrigin = 'anonymous'

  var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
  var url = DOMURL.createObjectURL(svgBlob);

  img.onload = function () {
    ctx.drawImage(img, 0, 0);
    DOMURL.revokeObjectURL(url);

    var imgURI = canvas
        .toDataURL('image/png')
        .replace('image/png', 'image/octet-stream');

    triggerDownload(imgURI);
  };

  img.src = url;
});
<button>svg to png</button>

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="161px" height="91px" version="1.1" style="background-color: rgb(255, 255, 255);">
<defs/>
<g transform="translate(0.5,0.5)">
<rect x="0" y="0" width="160" height="90" fill="#ffffff" stroke="#000000" pointer-events="none"/>
<path d="M 0 26 L 0 0 L 160 0 L 160 26 Z" fill="#dae8fc" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/>
<g transform="translate(48.5,7.5)">
<switch>

<text x="32" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica" font-weight="bold">Classname</text>
</switch>
</g>
<g transform="translate(5.5,32.5)">
<switch>


<text x="31" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">+ field: type</text>
</switch>
</g>
<path d="M 0 56 L 160 56" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g transform="translate(5.5,66.5)">
<switch>

<text x="56" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica">+ method(type): type</text>
</switch>
</g>
</g>
</svg>

<canvas id="canvas"></canvas>

你也可以试试Canvas2Image plugin

【讨论】:

  • 如果我使用 Canvas2Image 插件,是否需要再次转换我的 SVG?
  • 只需要一次。首先将您的 SVG 转换为 Canvas,然后调用 canvas2image 函数。
猜你喜欢
  • 1970-01-01
  • 2017-09-26
  • 1970-01-01
  • 2018-07-02
  • 1970-01-01
  • 2015-06-29
  • 2016-01-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多