Подтвердить что ты не робот

Сохранить встроенный SVG в формате JPEG/PNG/SVG

У меня встроенный SVG в моем html, и мне нужно сохранить его как JPEG, PNG или SVG.

Я пробовал несколько разных методов с преобразованием SVG в холст, а затем преобразовывал в JPEG, но я не смог заставить их работать.

Вот пример моего встроенного SVG.

.font {
	color: #ffffff;
	font-family: Roboto;
	font-weight: bold;
	text-transform: uppercase;
}
.name {
	font-size: 64pt;
}
.top-bar-text {
	font-size: 32pt;
}
.font tspan {
	dominant-baseline: middle;
}
<link href='http://fonts.googleapis.com/css?family=Roboto:700' rel='stylesheet' type='text/css'>

<svg width="256" height="256" id="icon">
  <rect class="bg1" id="bg_color_1" x="0" y="0" width="256" height="256" fill="#4cbc5a" />
  <path class="bg2" id="bg_color_2" d="M 0 96 L0,256 L256,256 L256,96 s -128 96 -256 0" fill="#08a21c" />
  <text id="left_corner_text" x="24" y="36" width="48" height="64" class="top_bar lct font top-bar-text" text-anchor="middle" fill="#ffffff"><tspan>1</tspan></text>
  <text id="right_corner_text" x="232" y="36" width="48" height="64" class="top_bar rct font top-bar-text" text-anchor="middle" fill="#ffffff"><tspan>2</tspan></text>
  <text id="line_1_text" transform="scale(1,2)" x="128" y="90" width="256" height="192" class="l1t font name" text-anchor="middle" fill="#ffffff"><tspan>ABC</tspan></text>
</svg>
4b9b3361

Ответ 1

В наше время это довольно просто.

Основная идея:

  • svg на холст
  • canvas to dataUrl
  • загрузить триггер с dataUrl

он действительно работает вне фрагмента stackoverflow

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();
  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" version="1.1" width="200" height="200">
  <rect x="10" y="10" width="50" height="50" />
  <text x="0" y="100">Look, i'm cool</text>
</svg>

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

Ответ 2

Вот решение, которое работает и в IE11.

Я только что проверил несколько различных методов этого, и хотя приведенный выше ответ Ciro Costa является фантастическим в том смысле, что он работает в Firefox и Chrome, он не работает в IE11. В IE11 происходит сбой из-за проблемы безопасности с отображением svg для canvas, для которого требуется реализация canvas, canvg. Вот решение с использованием canvg, которое довольно лаконично и работает в последних версиях Chrome, Firefox, Edge и IE11.

Fiddle: https://jsfiddle.net/StefanValentin/9mudw0ts/

DOM

<svg
  id="my-svg"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  version="1.1"
  width="200"
  height="200"
>
  <rect x="10" y="10" width="50" height="50" />
  <text x="0" y="100">Look, i'm cool</text>
</svg>

JavaScript

var svg = document.querySelector('#my-svg');
var data = (new XMLSerializer()).serializeToString(svg);
// We can just create a canvas element inline so you don't even need one on the DOM. Cool!
var canvas = document.createElement('canvas');
canvg(canvas, data, {
  renderCallback: function() {
    canvas.toBlob(function(blob) {
        download('MyImageName.png', blob);
    });
  }
});

Приведенная выше функция download может быть любой, что вы хотите сделать, поскольку существует множество способов инициировать загрузку через JavaScript. Вот тот, который мы используем, который работает во всех протестированных мной браузерах.

// Initiate download of blob
function download(
  filename, // string
  blob // Blob
) {
  if (window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveBlob(blob, filename);
  } else {
    const elem = window.document.createElement('a');
    elem.href = window.URL.createObjectURL(blob);
    elem.download = filename;
    document.body.appendChild(elem);
    elem.click();
    document.body.removeChild(elem);
  }
}

Ответ 3

Отработка @CiroCosta. 1 вариант, если у вас возникают проблемы при экспорте элемента, вы можете просто нарисовать изображение на холсте, прежде чем рисовать изображение svg

    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;

// get the raw image from the DOM
      var rawImage = document.getElementById('yourimageID');
      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(rawImage, 0, 0);
        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;
    });

работал для меня, но только для PNG и JPEG. В файлах SVG по-прежнему отображаются только встроенные элементы, а не теги

ОБНОВЛЕНИЕ: способ создания SVG, как это на самом деле, путем преобразования тега изображения в Base64 и установки, что как xlink: href в атрибутах изображения, как это:

<image id="crop" width="725" height="1764" xlink:href="data:image/png;base64,iVBORw0KGgo ... " />

и затем запускаем загрузку по всему URL-адресу svg следующим образом:

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 rawImage = document.getElementById('yourimageID');
      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);


       triggerDownload(url);
       DOMURL.revokeObjectURL(url);
      }
};

вы можете конвертировать PNG, как это здесь:

function getDataUri(url, callback) {
            var image = new Image();

            image.onload = function () {
                var canvas = document.createElement('canvas');
                canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size
                canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size

                canvas.getContext('2d').drawImage(this, 0, 0);

                // Get raw image data
                callback(canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, ''));

                // ... or get as Data URI
                callback(canvas.toDataURL('image/png'));
            };

            image.src = url;
        }

затем установите атрибут

getDataUri('localImagepath', function(dataUri) {
       image.setAttribute('xlink:href',dataUri);
});