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

Преобразование очень большого SVG в PNG с помощью <canvas>

Я пытаюсь преобразовать большой SVG (его URL-адрес данных около 750000 - 1000000 символов) в PNG, передав его URL-адрес через изображение и на холст, но изображение загружает только 1/4 из SVG.

Создание через:

var svg_xml = (new XMLSerializer()).serializeToString(svg),
    url = 'data:image/svg+xml;base64,' + btoa(svg_xml);

var img = new Image();
img.width = 730;
img.height = 300;
img.onload = function(){
    var canvas = document.create('canvas');
    canvas.width = 730;
    canvas.height = 300;

    var ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0, 730, 300);

    callbackFn(canvas.toDataURL('image/png');
}
img.src = url

Edit

Я пробовал реализовать canvg для рисования SVG, но DataURL дал результаты в виде чистого изображения:

var svg_xml = (new XMLSerializer()).serializeToString(svg);
var canvas = document.createElement('canvas');
canvas.width = 730;
canvas.height = 300;

var ctx = canvas.getContext('2d');
ctx.drawSvg(svg_xml, 0, 0, 730, 300);
callbackFn(canvas.toDataURL('image/png');

Есть ли что-то неправильное в методе, который я использовал?

Дальнейшее редактирование

Теперь я уверен, что это холст не смог нарисовать весь образ, поскольку я попытался реализовать решение Blob с тем же эффектом:

var svg_xml = (new XMLSerializer()).serializeToString(svg),
    blob = new Blob([svg_xml], {type:'image/svg+xml;charset=utf-8'}),
    url = window.URL.createObjectURL(blob);

var img = new Image();
img.width = 730;
img.height = 300;
img.onload = function(){
    var canvas = document.create('canvas');
    canvas.width = 730;
    canvas.height = 300;

    var ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0, 730, 300);

    window.URL.revokeObjectURL(url);
    callbackFn(canvas.toDataURL('image/png');
}
img.src = url   

Изображение снова загружается нормально и переходит к URL-адресу (до его отмены) также отображает изображение.

Длина холста dataURL не является последовательной, поэтому я не думаю, что maxing out, есть ли способ определить размер холста? Приложение поддерживается только для Chrome и FireFox.

4b9b3361

Ответ 1

Рабочая скрипта.

HTML:

    <div>
        <svg xmlns="http://www.w3.org/2000/svg"
              width="526" height="233">
          <rect x="13" y="14" width="500" height="200" rx="50" ry="100"
              fill="none" stroke="blue" stroke-width="10" />
        </svg>
        <a id='imgId'>Save</a>
    </div>
    <canvas></canvas>

JavaScript:

var svg = document.getElementsByTagName('svg')[0];
var svg_xml = (new XMLSerializer()).serializeToString(svg),
    blob = new Blob([svg_xml], {type:'image/svg+xml;charset=utf-8'}),
    url = window.URL.createObjectURL(blob);

var img = new Image();
img.width = 730;
img.height = 300;
img.onload = function(){
    var canvas = document.createElement('canvas');
    canvas.width = 730;
    canvas.height = 300;

    var ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0, 730, 300);

    window.URL.revokeObjectURL(url);
    var canvasdata = canvas.toDataURL('image/png');
    var a = document.getElementById('imgId');
    a.download = "export_" + Date.now() + ".png";
    a.href=canvasdata;   
}
img.src = url

Ваш вопрос:

Почему изображение загружает только 1/4 SVG?

Ответ:

Просто следуйте этим правилам:

  • x of <rect/> + width of <rect/> <= width of <svg/>
  • y of <rect/> + height of <rect/> <= height of <svg/>

Например:

<svg xmlns="http://www.w3.org/2000/svg" width="500" height="200">
     <rect x="10" y="10" width="550" height="250" rx="50" ry="100"
                  fill="none" stroke="blue" stroke-width="10" />
</svg>

Здесь x of <rect/>= 10, ширина <rect/>= 550, ширина <svg>= 500

поэтому 10 + 550 > 500

В этом случае изображение будет частично отображено.

Надеюсь, это решит вашу проблему.