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 图像显示得很好。所以我怀疑编码部分,但根据许多参考资料,它似乎并没有错。

我错过了什么?任何见解将不胜感激。

演示 link:https://codepen.io/Dongbin/pen/poRmbmg?editors=0010

外部图像(即 <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