Преобразование очень большого 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.
Ответы
Ответ 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
В этом случае изображение будет частично отображено.
Надеюсь, это решит вашу проблему.