Конвертируйте SVG в PNG и сохраняйте целостность CSS

В настоящее время я использую canvg() и Canvas2Image, чтобы скопировать SVG на холст, а затем преобразовать холст в PNG. Я хотел бы сохранить формат изображения и не использовать PDF.

Как я могу сохранить целостность CSS? Диаграмма сделана с помощью NVD3.js.

downloadPhoto: function() {
  var chartArea = document.getElementsByTagName('svg')[0].parentNode;
  var svg = chartArea.innerHTML;
  var canvas = document.createElement('canvas');
  canvas.setAttribute('width', chartArea.offsetWidth);
  canvas.setAttribute('height', chartArea.offsetHeight);
  canvas.setAttribute('display', 'none');

  canvas.setAttribute(
    'style',
    'position: absolute; ' +
    'top: ' + (-chartArea.offsetHeight * 2) + 'px;' +
    'left: ' + (-chartArea.offsetWidth * 2) + 'px;');
  document.body.appendChild(canvas);
  canvg(canvas, svg);
  Canvas2Image.saveAsPNG(canvas);
  canvas.parentNode.removeChild(canvas);
}

Исходный SVG

SVG преобразован в PNG


person collenjones    schedule 05.12.2013    source источник


Ответы (3)


Определения стиля для элементов svg, определенные в таблицах стилей, не применяются к сгенерированному холсту. Это можно исправить, добавив определения стилей к элементам svg перед вызовом canvg.

Вдохновленный этой статьей, я создал это :

function generateStyleDefs(svgDomElement) {
  var styleDefs = "";
  var sheets = document.styleSheets;
  for (var i = 0; i < sheets.length; i++) {
    var rules = sheets[i].cssRules;
    for (var j = 0; j < rules.length; j++) {
      var rule = rules[j];
      if (rule.style) {
        var selectorText = rule.selectorText;
        var elems = svgDomElement.querySelectorAll(selectorText);

        if (elems.length) {
          styleDefs += selectorText + " { " + rule.style.cssText + " }\n";
        }
      }
    }
  }

  var s = document.createElement('style');
  s.setAttribute('type', 'text/css');
  s.innerHTML = "<![CDATA[\n" + styleDefs + "\n]]>";
  //somehow cdata section doesn't always work; you could use this instead:
  //s.innerHTML = styleDefs;

  var defs = document.createElement('defs');
  defs.appendChild(s);
  svgDomElement.insertBefore(defs, svgDomElement.firstChild);
}

// generate style definitions on the svg element(s)
generateStyleDefs(document.getElementById('svgElementId'));
person R. Oosterholt    schedule 11.08.2015

Ключевым моментом здесь является то, что все правила стиля должны быть частью SVG, а не во внешних файлах стилей. Таким образом, вам нужно будет пройти весь CSS для NVD3 и установить все эти атрибуты в коде. Все, что установлено через внешнюю таблицу стилей, будет проигнорировано.

person Lars Kotthoff    schedule 05.12.2013

просто чтобы сделать ответ @Lars Kottoff более конкретным. "пример экспорта png напрямую из svg" содержит рабочий пример. фрагмент кода/суть пытается сначала применить все css к встроенному svg, а затем нарисовать изображение на холсте и экспортировать данные в формате png. (внутренне он принял svg-crowbarкод). и я применяю этот метод в своем проекте, и он работает без сбоев - кнопка загрузки, которая может загрузить изображение svg, созданное с помощью nvd3 .

person Dyno Fu    schedule 31.12.2016