将带有图像的SVG转换为PNG会省略图像

时间:2017-05-03 21:04:29

标签: javascript html5-canvas png

我想将SVG转换为PNG。但我的SVG包含图像,当我尝试用画布将SVG转换为PNG时,我的图像不会出现在我的PNG中。下面是我要转换的svg的一个例子。

<svg viewBox="0 0 1150 780" version="1.1" xmlns="http://www.w3.org/2000/svg" width="900" height="610">
    <defs>
        <pattern id="striped" patternUnits="userSpaceOnUse" width="4" height="4">
            <rect x="0" y="0" width="4" height="4" fill="transparent"></rect>
            <path d="M-1,1 l2,-2 M0,4 l4,-4 M3,5 l2,-2" style="stroke: #7F7C5D; stroke-width: 1;"></path>
        </pattern>
        <pattern id="goal" patternUnits="userSpaceOnUse" width="2" height="2">
            <rect x="0" y="0" width="2" height="2" fill="transparent"></rect>
            <line x1="0" y1="0" x2="1" y2="0" style="stroke: #ffffff; stroke-width: 1;"></line>
            <line x1="1" y1="0" x2="1" y2="1" style="stroke: #ffffff; stroke-width: 1;"></line>
        </pattern>
    </defs>
    <path d="M 0,0 h1150 v780 h-1150z" fill="green"></path>
    <polyline points="575,730 575,50 1100,50 1100,730 50,730 50,50 575,50" style="stroke: #fff; stroke-width: 1.2; fill: none;"></polyline>
    <circle cx="575" cy="390" style="stroke: #ffffff; stroke-width: 1.2; fill: none;" r="91.5"></circle>
    <circle cx="160" cy="390" style="stroke: #ffffff; fill: #ffffff;" r="1.5"></circle>
    <circle cx="990" cy="390" style="stroke: #ffffff; fill: #ffffff;" r="1.5"></circle>
    <path d="M251.5,390 a91.5,91.5 0 0,0 -36.5,-73.4 M251.5,390 a91.5,91.5 0 0,1 -36.5,73.4 M898.5,390 a91.5,95.5 0 0,0 36.5,73.4 M898.5,390 a91.5,95.5 0 0,1 36.5,-73.4" style="stroke: #fff; stroke-width: 1.2; fill: none;"></path>
    <path d="M 50 60 Q 60 60 60 50 M 1090 50 Q 1090 60 1100 60 M 50 720 Q 60 720 60 730 M 1090 730 Q 1090 720 1100 720" style="stroke: #fff; stroke-width: 1.2; fill: none;"></path>
    <polyline points="50,426.6 35,426.6 35,353.4 50,353.4" style="stroke: #ffffff; stroke-width: 0.75; fill: url(#goal);"></polyline>
    <polyline points="1100,426.6 1115,426.6 1115,353.4 1100,353.4" style="stroke: #ffffff; stroke-width: 0.75; fill: url(#goal);"></polyline>
    <polyline points="50,481.6 105,481.6 105,298.4 50,298.4 50,591.6 215,591.6 215,188.4 50,188.4" style="stroke: #fff; stroke-width: 1.2; fill: none;"></polyline>
    <polyline points="1100,481.6 1045,481.6 1045,298.4 1100,298.4 1100,591.6 935,591.6 935,188.4 1100,188.4" style="stroke: #fff; stroke-width: 1.2; fill: none;"></polyline>
    <g top="0" left="0" class="contents" transform="matrix(1,0,0,1,0,0)">
        <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="logo.png" preserveAspectRatio="none" x="41.2%" y="37.2%" width="200" height="200" style="opacity: 0.3;">
        </image>
    </g>
</svg>

我的javascript函数将SVG转换为PNG:

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

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

      a.dispatchEvent(evt);
    }

    document.querySelector('button').addEventListener('click', function () {
      var canvas = document.createElement('canvas');
      canvas.setAttribute("width", 900);
      canvas.setAttribute("height", 610);
      var svg = document.querySelector('svg');
      var ctx = canvas.getContext('2d');
      var data = (new XMLSerializer()).serializeToString(svg);
      var DOMURL = window.URL || window.webkitURL || window;

      var img = new Image();
      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;
    });

你知道怎么做吗?

0 个答案:

没有答案