将 SVG 加载到 canvas 以获取 base64 dataurl
Load SVG into canvas to get base64 dataurl
我的 html 中有这个 SVG :
<svg xmlns="http://www.w3.org/2000/svg" class="bi flex-shrink-0 me-2 green-check" width="24" height="24" role="img" aria-label="moon"><title>Free</title><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#check-green-symbol"/></svg>
“use”标签指向的符号是:
<symbol id="check-green-symbol" viewBox="0 0 512 512" id=".3539536280039488" xmlns="http://www.w3.org/2000/svg">
<path d="M437.019 74.981C388.668 26.629 324.38.001 256 .001S123.332 26.629 74.98 74.981C26.629 123.333 0 187.621 0 256.001S26.629 388.669 74.98 437.02C123.332 485.371 187.62 512 256 512c68.381 0 132.668-26.629 181.019-74.98C485.371 388.667 512 324.379 512 255.999s-26.629-132.666-74.981-181.018zM256 477.453C133.891 477.453 34.547 378.11 34.547 256S133.891 34.548 256 34.548s221.453 99.343 221.453 221.453S378.109 477.453 256 477.453z" fill="green" />
<path d="M393.953 160.709c-21.906-21.904-57.355-21.906-79.264-.001l-89.238 89.239-28.14-28.141c-21.903-21.903-57.354-21.906-79.262 0-21.852 21.852-21.853 57.408 0 79.26l67.772 67.772c10.586 10.586 24.66 16.416 39.631 16.416s29.045-5.83 39.631-16.415l128.87-128.87c21.852-21.851 21.852-57.408 0-79.26zm-24.431 54.832L240.653 344.41c-4.061 4.06-9.459 6.297-15.202 6.297s-11.142-2.237-15.202-6.297l-67.771-67.772c-8.383-8.383-8.383-22.022 0-30.403 8.402-8.401 22-8.404 30.404 0l40.355 40.355a17.274 17.274 0 0 0 24.428 0l101.453-101.453c8.402-8.401 22.002-8.404 30.404 0 8.384 8.383 8.384 22.022 0 30.404z" fill="green" stroke="green" stroke-width="50" />
</symbol>
这在页面加载时正确显示(即,它使用我指的使用标签的符号)。
我想获取此 SVG 并获取 base64 dataurl(将其转换为图像)。
我尝试使用此代码但没有成功,它总是给我一张 white/blank 图片。
function convertSVG(classname) {
var serializer = new XMLSerializer();
var svgElement = document.querySelector(".green-check"); //hardcoded for test
var svgData = new XMLSerializer().serializeToString(svgElement);
console.log(svgData);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
var img = new Image;
img.width = canvas.width = svgElement.clientWidth;
img.height = canvas.height = svgElement.clientHeight;
img.src = 'data:image/svg+xml,' + encodeURIComponent(svgData);
ctx.drawImage( img, 0, 0, img.width, img.height );
console.log(canvas.toDataURL());
return canvas.toDataURL();
}
我在控制台中得到的 base64 是这样的:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAARZJREFUSEuVVlkWwyAIxPsfOnkqKsiwmJ+2KoFZwDbaTyOi7/zs3+RSsi0D7zDea9To2ynM+8DCOa833QQDAe96xY91gEZDX+gbtXPWjzLJwgT6tEigKR8VJTzhPJZqSItJADiTdHmgFAJcdQLES7ytI6jAjADVjaJcBIBUEvkgk/wmpuBk/cNvtcSynjVlw6oEAHm50fHBjvh+ZNUb5rebq9JjNysJRRWRwahAGhiYoNxK5ytThN3oifwASmjgRx17Ayq43DFZHc1kl0S3Q3BBBD1hqisNmHk3ufNnX12ZTU0XgsGTNM/UICnl1fuqLmM7j6KwCJ5RUmQ1TctzWkSt/wehZZcGFQ4S72OzTPYTa76duDX/Aaq1oyLeMBeVAAAAAElFTkSuQmCC
我还尝试序列化“use”标签指向的元素
“罗伯特朗森”建议,这部分代码:
var serializer = new XMLSerializer();
var svgElement = document.querySelector(".green-check");
var svgElement2 = document.querySelector("#check-green-symbol");
svgElement.innerHTML = svgElement2.innerHTML;
var svgData = new XMLSerializer().serializeToString(svgElement);
序列化后的字符串如下所示:
<svg xmlns="http://www.w3.org/2000/svg" class="bi flex-shrink-0 me-2 green-check" width="24" height="24" role="img" aria-label="moon"> <path d="M437.019 74.981C388.668 26.629 324.38.001 256 .001S123.332 26.629 74.98 74.981C26.629 123.333 0 187.621 0 256.001S26.629 388.669 74.98 437.02C123.332 485.371 187.62 512 256 512c68.381 0 132.668-26.629 181.019-74.98C485.371 388.667 512 324.379 512 255.999s-26.629-132.666-74.981-181.018zM256 477.453C133.891 477.453 34.547 378.11 34.547 256S133.891 34.548 256 34.548s221.453 99.343 221.453 221.453S378.109 477.453 256 477.453z" fill="green"/> <path d="M393.953 160.709c-21.906-21.904-57.355-21.906-79.264-.001l-89.238 89.239-28.14-28.141c-21.903-21.903-57.354-21.906-79.262 0-21.852 21.852-21.853 57.408 0 79.26l67.772 67.772c10.586 10.586 24.66 16.416 39.631 16.416s29.045-5.83 39.631-16.415l128.87-128.87c21.852-21.851 21.852-57.408 0-79.26zm-24.431 54.832L240.653 344.41c-4.061 4.06-9.459 6.297-15.202 6.297s-11.142-2.237-15.202-6.297l-67.771-67.772c-8.383-8.383-8.383-22.022 0-30.403 8.402-8.401 22-8.404 30.404 0l40.355 40.355a17.274 17.274 0 0 0 24.428 0l101.453-101.453c8.402-8.401 22.002-8.404 30.404 0 8.384 8.383 8.384 22.022 0 30.404z" fill="green" stroke="green" stroke-width="50"/> </svg>
结果是一样的,我仍然得到一个空白图像作为输出。
我做错了什么?欢迎任何其他提示。
非常感谢。
好的,这是一个包含原始<symbol>
的示例。您可以看到它仅在 <symbol>
是序列化的 SVG 的一部分时有效(在工作示例中,我将两个 class 名称重命名为“green-check2”和“check-green-symbol2 ").
我稍微重新安排了函数,包括内存图像的事件侦听器。此处可能不需要,但在网络上等时是个好习惯。
convertSVG(".green-check", "img");
convertSVG(".green-check2", "img2");
function convertSVG(classname, image) {
var serializer = new XMLSerializer();
var svgElement = document.querySelector(classname);
var svgData = new XMLSerializer().serializeToString(svgElement);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
var img = new Image;
img.addEventListener('load', e => {
canvas.width = e.target.width;
canvas.height = e.target.height;
ctx.drawImage(e.target, 0, 0, e.target.width, e.target.height);
document.getElementById(image).src = canvas.toDataURL();
});
img.src = 'data:image/svg+xml;base64,' + btoa(svgData);
}
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
<symbol id="check-green-symbol" viewBox="0 0 512 512" id=".3539536280039488" xmlns="http://www.w3.org/2000/svg">
<path d="M437.019 74.981C388.668 26.629 324.38.001 256 .001S123.332 26.629 74.98 74.981C26.629 123.333 0 187.621 0 256.001S26.629 388.669 74.98 437.02C123.332 485.371 187.62 512 256 512c68.381 0 132.668-26.629 181.019-74.98C485.371 388.667 512 324.379 512 255.999s-26.629-132.666-74.981-181.018zM256 477.453C133.891 477.453 34.547 378.11 34.547 256S133.891 34.548 256 34.548s221.453 99.343 221.453 221.453S378.109 477.453 256 477.453z" fill="green" />
<path d="M393.953 160.709c-21.906-21.904-57.355-21.906-79.264-.001l-89.238 89.239-28.14-28.141c-21.903-21.903-57.354-21.906-79.262 0-21.852 21.852-21.853 57.408 0 79.26l67.772 67.772c10.586 10.586 24.66 16.416 39.631 16.416s29.045-5.83 39.631-16.415l128.87-128.87c21.852-21.851 21.852-57.408 0-79.26zm-24.431 54.832L240.653 344.41c-4.061 4.06-9.459 6.297-15.202 6.297s-11.142-2.237-15.202-6.297l-67.771-67.772c-8.383-8.383-8.383-22.022 0-30.403 8.402-8.401 22-8.404 30.404 0l40.355 40.355a17.274 17.274 0 0 0 24.428 0l101.453-101.453c8.402-8.401 22.002-8.404 30.404 0 8.384 8.383 8.384 22.022 0 30.404z" fill="green" stroke="green" stroke-width="50" />
</symbol>
</svg>
<p>The original setup (class=green-check):
<svg xmlns="http://www.w3.org/2000/svg" class="green-check" width="24" height="24" role="img" aria-label="moon">
<use href="#check-green-symbol"/>
</svg>
</p>
<p>The new setup (class=green-check2 and class=check-green-symbol2):
<svg xmlns="http://www.w3.org/2000/svg" class="green-check2" width="24" height="24" role="img" aria-label="moon">
<symbol id="check-green-symbol2" viewBox="0 0 512 512" id=".3539536280039488" xmlns="http://www.w3.org/2000/svg">
<path d="M437.019 74.981C388.668 26.629 324.38.001 256 .001S123.332 26.629 74.98 74.981C26.629 123.333 0 187.621 0 256.001S26.629 388.669 74.98 437.02C123.332 485.371 187.62 512 256 512c68.381 0 132.668-26.629 181.019-74.98C485.371 388.667 512 324.379 512 255.999s-26.629-132.666-74.981-181.018zM256 477.453C133.891 477.453 34.547 378.11 34.547 256S133.891 34.548 256 34.548s221.453 99.343 221.453 221.453S378.109 477.453 256 477.453z" fill="green" />
<path d="M393.953 160.709c-21.906-21.904-57.355-21.906-79.264-.001l-89.238 89.239-28.14-28.141c-21.903-21.903-57.354-21.906-79.262 0-21.852 21.852-21.853 57.408 0 79.26l67.772 67.772c10.586 10.586 24.66 16.416 39.631 16.416s29.045-5.83 39.631-16.415l128.87-128.87c21.852-21.851 21.852-57.408 0-79.26zm-24.431 54.832L240.653 344.41c-4.061 4.06-9.459 6.297-15.202 6.297s-11.142-2.237-15.202-6.297l-67.771-67.772c-8.383-8.383-8.383-22.022 0-30.403 8.402-8.401 22-8.404 30.404 0l40.355 40.355a17.274 17.274 0 0 0 24.428 0l101.453-101.453c8.402-8.401 22.002-8.404 30.404 0 8.384 8.383 8.384 22.022 0 30.404z" fill="green" stroke="green" stroke-width="50" />
</symbol>
<use href="#check-green-symbol2"/>
</svg>
</p>
<p>The original output (blank image): <img id="img" /></p>
<p>The new output (including serialized symbol): <img id="img2" /></p>
我的 html 中有这个 SVG :
<svg xmlns="http://www.w3.org/2000/svg" class="bi flex-shrink-0 me-2 green-check" width="24" height="24" role="img" aria-label="moon"><title>Free</title><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#check-green-symbol"/></svg>
“use”标签指向的符号是:
<symbol id="check-green-symbol" viewBox="0 0 512 512" id=".3539536280039488" xmlns="http://www.w3.org/2000/svg">
<path d="M437.019 74.981C388.668 26.629 324.38.001 256 .001S123.332 26.629 74.98 74.981C26.629 123.333 0 187.621 0 256.001S26.629 388.669 74.98 437.02C123.332 485.371 187.62 512 256 512c68.381 0 132.668-26.629 181.019-74.98C485.371 388.667 512 324.379 512 255.999s-26.629-132.666-74.981-181.018zM256 477.453C133.891 477.453 34.547 378.11 34.547 256S133.891 34.548 256 34.548s221.453 99.343 221.453 221.453S378.109 477.453 256 477.453z" fill="green" />
<path d="M393.953 160.709c-21.906-21.904-57.355-21.906-79.264-.001l-89.238 89.239-28.14-28.141c-21.903-21.903-57.354-21.906-79.262 0-21.852 21.852-21.853 57.408 0 79.26l67.772 67.772c10.586 10.586 24.66 16.416 39.631 16.416s29.045-5.83 39.631-16.415l128.87-128.87c21.852-21.851 21.852-57.408 0-79.26zm-24.431 54.832L240.653 344.41c-4.061 4.06-9.459 6.297-15.202 6.297s-11.142-2.237-15.202-6.297l-67.771-67.772c-8.383-8.383-8.383-22.022 0-30.403 8.402-8.401 22-8.404 30.404 0l40.355 40.355a17.274 17.274 0 0 0 24.428 0l101.453-101.453c8.402-8.401 22.002-8.404 30.404 0 8.384 8.383 8.384 22.022 0 30.404z" fill="green" stroke="green" stroke-width="50" />
</symbol>
这在页面加载时正确显示(即,它使用我指的使用标签的符号)。
我想获取此 SVG 并获取 base64 dataurl(将其转换为图像)。
我尝试使用此代码但没有成功,它总是给我一张 white/blank 图片。
function convertSVG(classname) {
var serializer = new XMLSerializer();
var svgElement = document.querySelector(".green-check"); //hardcoded for test
var svgData = new XMLSerializer().serializeToString(svgElement);
console.log(svgData);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
var img = new Image;
img.width = canvas.width = svgElement.clientWidth;
img.height = canvas.height = svgElement.clientHeight;
img.src = 'data:image/svg+xml,' + encodeURIComponent(svgData);
ctx.drawImage( img, 0, 0, img.width, img.height );
console.log(canvas.toDataURL());
return canvas.toDataURL();
}
我在控制台中得到的 base64 是这样的:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAARZJREFUSEuVVlkWwyAIxPsfOnkqKsiwmJ+2KoFZwDbaTyOi7/zs3+RSsi0D7zDea9To2ynM+8DCOa833QQDAe96xY91gEZDX+gbtXPWjzLJwgT6tEigKR8VJTzhPJZqSItJADiTdHmgFAJcdQLES7ytI6jAjADVjaJcBIBUEvkgk/wmpuBk/cNvtcSynjVlw6oEAHm50fHBjvh+ZNUb5rebq9JjNysJRRWRwahAGhiYoNxK5ytThN3oifwASmjgRx17Ayq43DFZHc1kl0S3Q3BBBD1hqisNmHk3ufNnX12ZTU0XgsGTNM/UICnl1fuqLmM7j6KwCJ5RUmQ1TctzWkSt/wehZZcGFQ4S72OzTPYTa76duDX/Aaq1oyLeMBeVAAAAAElFTkSuQmCC
我还尝试序列化“use”标签指向的元素 “罗伯特朗森”建议,这部分代码:
var serializer = new XMLSerializer();
var svgElement = document.querySelector(".green-check");
var svgElement2 = document.querySelector("#check-green-symbol");
svgElement.innerHTML = svgElement2.innerHTML;
var svgData = new XMLSerializer().serializeToString(svgElement);
序列化后的字符串如下所示:
<svg xmlns="http://www.w3.org/2000/svg" class="bi flex-shrink-0 me-2 green-check" width="24" height="24" role="img" aria-label="moon"> <path d="M437.019 74.981C388.668 26.629 324.38.001 256 .001S123.332 26.629 74.98 74.981C26.629 123.333 0 187.621 0 256.001S26.629 388.669 74.98 437.02C123.332 485.371 187.62 512 256 512c68.381 0 132.668-26.629 181.019-74.98C485.371 388.667 512 324.379 512 255.999s-26.629-132.666-74.981-181.018zM256 477.453C133.891 477.453 34.547 378.11 34.547 256S133.891 34.548 256 34.548s221.453 99.343 221.453 221.453S378.109 477.453 256 477.453z" fill="green"/> <path d="M393.953 160.709c-21.906-21.904-57.355-21.906-79.264-.001l-89.238 89.239-28.14-28.141c-21.903-21.903-57.354-21.906-79.262 0-21.852 21.852-21.853 57.408 0 79.26l67.772 67.772c10.586 10.586 24.66 16.416 39.631 16.416s29.045-5.83 39.631-16.415l128.87-128.87c21.852-21.851 21.852-57.408 0-79.26zm-24.431 54.832L240.653 344.41c-4.061 4.06-9.459 6.297-15.202 6.297s-11.142-2.237-15.202-6.297l-67.771-67.772c-8.383-8.383-8.383-22.022 0-30.403 8.402-8.401 22-8.404 30.404 0l40.355 40.355a17.274 17.274 0 0 0 24.428 0l101.453-101.453c8.402-8.401 22.002-8.404 30.404 0 8.384 8.383 8.384 22.022 0 30.404z" fill="green" stroke="green" stroke-width="50"/> </svg>
结果是一样的,我仍然得到一个空白图像作为输出。
我做错了什么?欢迎任何其他提示。
非常感谢。
好的,这是一个包含原始<symbol>
的示例。您可以看到它仅在 <symbol>
是序列化的 SVG 的一部分时有效(在工作示例中,我将两个 class 名称重命名为“green-check2”和“check-green-symbol2 ").
我稍微重新安排了函数,包括内存图像的事件侦听器。此处可能不需要,但在网络上等时是个好习惯。
convertSVG(".green-check", "img");
convertSVG(".green-check2", "img2");
function convertSVG(classname, image) {
var serializer = new XMLSerializer();
var svgElement = document.querySelector(classname);
var svgData = new XMLSerializer().serializeToString(svgElement);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
var img = new Image;
img.addEventListener('load', e => {
canvas.width = e.target.width;
canvas.height = e.target.height;
ctx.drawImage(e.target, 0, 0, e.target.width, e.target.height);
document.getElementById(image).src = canvas.toDataURL();
});
img.src = 'data:image/svg+xml;base64,' + btoa(svgData);
}
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
<symbol id="check-green-symbol" viewBox="0 0 512 512" id=".3539536280039488" xmlns="http://www.w3.org/2000/svg">
<path d="M437.019 74.981C388.668 26.629 324.38.001 256 .001S123.332 26.629 74.98 74.981C26.629 123.333 0 187.621 0 256.001S26.629 388.669 74.98 437.02C123.332 485.371 187.62 512 256 512c68.381 0 132.668-26.629 181.019-74.98C485.371 388.667 512 324.379 512 255.999s-26.629-132.666-74.981-181.018zM256 477.453C133.891 477.453 34.547 378.11 34.547 256S133.891 34.548 256 34.548s221.453 99.343 221.453 221.453S378.109 477.453 256 477.453z" fill="green" />
<path d="M393.953 160.709c-21.906-21.904-57.355-21.906-79.264-.001l-89.238 89.239-28.14-28.141c-21.903-21.903-57.354-21.906-79.262 0-21.852 21.852-21.853 57.408 0 79.26l67.772 67.772c10.586 10.586 24.66 16.416 39.631 16.416s29.045-5.83 39.631-16.415l128.87-128.87c21.852-21.851 21.852-57.408 0-79.26zm-24.431 54.832L240.653 344.41c-4.061 4.06-9.459 6.297-15.202 6.297s-11.142-2.237-15.202-6.297l-67.771-67.772c-8.383-8.383-8.383-22.022 0-30.403 8.402-8.401 22-8.404 30.404 0l40.355 40.355a17.274 17.274 0 0 0 24.428 0l101.453-101.453c8.402-8.401 22.002-8.404 30.404 0 8.384 8.383 8.384 22.022 0 30.404z" fill="green" stroke="green" stroke-width="50" />
</symbol>
</svg>
<p>The original setup (class=green-check):
<svg xmlns="http://www.w3.org/2000/svg" class="green-check" width="24" height="24" role="img" aria-label="moon">
<use href="#check-green-symbol"/>
</svg>
</p>
<p>The new setup (class=green-check2 and class=check-green-symbol2):
<svg xmlns="http://www.w3.org/2000/svg" class="green-check2" width="24" height="24" role="img" aria-label="moon">
<symbol id="check-green-symbol2" viewBox="0 0 512 512" id=".3539536280039488" xmlns="http://www.w3.org/2000/svg">
<path d="M437.019 74.981C388.668 26.629 324.38.001 256 .001S123.332 26.629 74.98 74.981C26.629 123.333 0 187.621 0 256.001S26.629 388.669 74.98 437.02C123.332 485.371 187.62 512 256 512c68.381 0 132.668-26.629 181.019-74.98C485.371 388.667 512 324.379 512 255.999s-26.629-132.666-74.981-181.018zM256 477.453C133.891 477.453 34.547 378.11 34.547 256S133.891 34.548 256 34.548s221.453 99.343 221.453 221.453S378.109 477.453 256 477.453z" fill="green" />
<path d="M393.953 160.709c-21.906-21.904-57.355-21.906-79.264-.001l-89.238 89.239-28.14-28.141c-21.903-21.903-57.354-21.906-79.262 0-21.852 21.852-21.853 57.408 0 79.26l67.772 67.772c10.586 10.586 24.66 16.416 39.631 16.416s29.045-5.83 39.631-16.415l128.87-128.87c21.852-21.851 21.852-57.408 0-79.26zm-24.431 54.832L240.653 344.41c-4.061 4.06-9.459 6.297-15.202 6.297s-11.142-2.237-15.202-6.297l-67.771-67.772c-8.383-8.383-8.383-22.022 0-30.403 8.402-8.401 22-8.404 30.404 0l40.355 40.355a17.274 17.274 0 0 0 24.428 0l101.453-101.453c8.402-8.401 22.002-8.404 30.404 0 8.384 8.383 8.384 22.022 0 30.404z" fill="green" stroke="green" stroke-width="50" />
</symbol>
<use href="#check-green-symbol2"/>
</svg>
</p>
<p>The original output (blank image): <img id="img" /></p>
<p>The new output (including serialized symbol): <img id="img2" /></p>