svg 斑点图像在编码后被破坏
svg blobbed image is broken after encoding it
我尝试将图像解析为 blob 并在 svg 的 image
标签中引用它:
`<image xlink:href="${imgRef}" height="${h}" width="${w}" stroke="red" x="50%" y="50%" transform="translate(${-(w / 2)}, ${-(h / 2) - 4})"/>`
并将其嵌入 svg:
const w = 100; // width
const h = 65; // height
const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" xmlns:xlink="http://www.w3.org/1999/xlink">` +
`<image xlink:href="${imgRef}" height="${h}" width="${w}" stroke="red" x="50%" y="50%" transform="translate(${-(w / 2)}, ${-(h / 2) - 4})"/>` +
`</svg>`;
然后我尝试通过 'data:image/svg+xml;,' + encodeURIComponent(svgString)
对它进行编码,但它显示了一个损坏的图像。我在通过 document.body.innerHTML = svgString
编码之前测试了上面的 svg 字符串,并且 svg 图像显示得很好。所以我怀疑编码部分,但根据许多参考资料,它似乎并没有错。
我错过了什么?任何见解将不胜感激。
外部图像(即 <img>
或 CSS background-image
)必须是独立的。它们不能引用图像本身之外的资源。基本上这意味着如果您需要引用任何文件(位图图像、字体等)作为 SVG 图像的一部分,它们需要是数据 URL。
修复方法是不使用 canvas.toBlob()
。请改用 canvas.toDataURL()
。
const imgRef = canvas.toDataURL();
const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" ` +
`xmlns:xlink="http://www.w3.org/1999/xlink">` +
`<image xlink:href="${imgRef}" height="125" width="200"/>` +
`</svg>`;
更新
如果您对 SVG 进行 URI 编码,它应该可以工作。
参见:https://jsfiddle.net/dxkeqfnr/
const img = new Image();
img.src = 'https://live.staticflickr.com/7272/7633179468_3e19e45a0c_b.jpg';
img.crossOrigin="anonymous"
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 125;
canvas.getContext('2d').drawImage(img, 0, 0, 200, 125);
canvas.toBlob((blob) => {
const imgRef = URL.createObjectURL(blob);
const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="200" height="125" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="${imgRef}" height="125" width="200"/></svg>`;
//div.innerHTML = svgString;
const newImg = new Image();
newImg.src = `data:image/svg+xml,${encodeURIComponent(svgString)}`;
document.body.appendChild(newImg);
});
};
它在 Firefox 中有效,但在 Chrome 中无效。这似乎是一个错误。 I have reported the bug to Chrome
我尝试将图像解析为 blob 并在 svg 的 image
标签中引用它:
`<image xlink:href="${imgRef}" height="${h}" width="${w}" stroke="red" x="50%" y="50%" transform="translate(${-(w / 2)}, ${-(h / 2) - 4})"/>`
并将其嵌入 svg:
const w = 100; // width
const h = 65; // height
const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" xmlns:xlink="http://www.w3.org/1999/xlink">` +
`<image xlink:href="${imgRef}" height="${h}" width="${w}" stroke="red" x="50%" y="50%" transform="translate(${-(w / 2)}, ${-(h / 2) - 4})"/>` +
`</svg>`;
然后我尝试通过 'data:image/svg+xml;,' + encodeURIComponent(svgString)
对它进行编码,但它显示了一个损坏的图像。我在通过 document.body.innerHTML = svgString
编码之前测试了上面的 svg 字符串,并且 svg 图像显示得很好。所以我怀疑编码部分,但根据许多参考资料,它似乎并没有错。
我错过了什么?任何见解将不胜感激。
外部图像(即 <img>
或 CSS background-image
)必须是独立的。它们不能引用图像本身之外的资源。基本上这意味着如果您需要引用任何文件(位图图像、字体等)作为 SVG 图像的一部分,它们需要是数据 URL。
修复方法是不使用 canvas.toBlob()
。请改用 canvas.toDataURL()
。
const imgRef = canvas.toDataURL();
const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" ` +
`xmlns:xlink="http://www.w3.org/1999/xlink">` +
`<image xlink:href="${imgRef}" height="125" width="200"/>` +
`</svg>`;
更新
如果您对 SVG 进行 URI 编码,它应该可以工作。
参见:https://jsfiddle.net/dxkeqfnr/
const img = new Image();
img.src = 'https://live.staticflickr.com/7272/7633179468_3e19e45a0c_b.jpg';
img.crossOrigin="anonymous"
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 125;
canvas.getContext('2d').drawImage(img, 0, 0, 200, 125);
canvas.toBlob((blob) => {
const imgRef = URL.createObjectURL(blob);
const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="200" height="125" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="${imgRef}" height="125" width="200"/></svg>`;
//div.innerHTML = svgString;
const newImg = new Image();
newImg.src = `data:image/svg+xml,${encodeURIComponent(svgString)}`;
document.body.appendChild(newImg);
});
};
它在 Firefox 中有效,但在 Chrome 中无效。这似乎是一个错误。 I have reported the bug to Chrome