image - 替代 unescape() 并将图像保存为 base64

标签 image svg utf-8 base64 escaping

我正在尝试将 svg 转换为 png,使用代码 here作为我转换的基础。

请注意以下代码(已缩短为仅与我稍后描述的错误相关的代码):

let svgData = new XMLSerializer().serializeToString(target); // 'target' is an svg element that is passed to us

let canvas = document.createElement('canvas');

let ctxt = canvas.getContext('2d');

let img = document.createElement('img');

img.setAttribute(
    'src',
    'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgData)))
);

ctxt.drawImage(img, 0, 0);

上面的代码工作正常。但是它有一个问题。请注意,这是这行代码:

'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgData)))

在这行代码中,使用了unescape()函数,然而却是deprecated ,我必须使用替代方法。根据文档,我应该使用 decodeURIComponent(),但这不是一个可行的解决方案,因为当我用 decodeURIComponent() 更新上面的代码时,结果是:

'data:image/svg+xml;base64,' + window.btoa(decodeURIComponent(encodeURIComponent(svgData)))

所以基本上我会编码然后解码。这与这样做相同:

'data:image/svg+xml;base64,' + window.btoa(svgData)

现在,有了新的更新代码,如果源 svg 只包含英文字符,一切都可以。但是,如果 svg 包含非英语字符(例如,包含日文单词 テマテ),则下一行代码 ctxt.drawImage(img, 0, 0); ,抛出错误。错误消息是 DOMException: String contains an invalid character

到目前为止,总结一下:

  1. 原始代码可以很好地处理英文和非英文字符,但使用了被弃用的 unescape() 函数。所以我应该使用其他东西。

  2. 更新后的代码,不进行编码和解码,在使用非英文字符时会导致异常。

现在,问题 1,我该怎么做才能使用 base64 从包含非英语字符的 svg 创建图像?

作为替代解决方案,我这样做了

'data:image/svg+xml;utf8,' + svgData

基本上,我没有使用base64,而是utf8。这工作得很好,但我不确定这是否是正确的解决方案。

那么,问题 2,使用 utf8 是一种常见的做法吗?它与 base64 相比有什么问题吗?

谢谢。


根据@RobertLongson 的以下评论,我将代码更新为:

'data:image/svg+xml;utf8,' + encodeURIComponent(svgData)

这适用于包含英文和非英文字符的 svg 元素。

现在,问题 3,这是正确的吗?

对基本问题表示歉意。我不熟悉这个。谢谢。

最佳答案

在这个例子中,我试图避免使用提到的函数来转换为 base64,而是使用 FileReader特别是 readAsDataURL用于返回数据 URI 的函数。我知道带有回调的代码有点复杂,但它确实有效。

据我所知谷歌翻译 tomato 翻译成🍅。

let svg01 = document.getElementById('svg01');
let canvas = document.getElementById('canvas01');
let img = document.getElementById('img01');
let ctx = canvas.getContext('2d');

canvas01.width = svg01.getAttribute('width');
canvas01.height = svg01.getAttribute('height');

let svgData = new XMLSerializer().serializeToString(svg01);

// create a File object
let file = new File([svgData], 'svg.svg', {
  type: "image/svg+xml"
});

// and a reader
let reader = new FileReader();

reader.addEventListener('load', e => {
  let img = new Image();
  // wait for it to got load
  img.addEventListener('load', e => {
    // update canvas with new image
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(e.target, 0, 0);
    // create PNG image based on canvas
    img01.src = canvas.toDataURL("image/png");
  });
  img.src = e.target.result;
});
// read the file as a data URL
reader.readAsDataURL(file);
<p>SVG embedded:</p>
<svg id="svg01" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 20" width="300" height="60">
  <rect width="100" height="20" fill="silver" rx="5"/>
  <text font-size="7" x="50" y="10" text-anchor="middle"
  dominant-baseline="middle">Japanese word: トマト 🍅</text>
</svg>
<p>Canvas image:</p>
<canvas id="canvas01"></canvas>
<p>PNG image:</p>
<p><img id="img01" /></p>

关于image - 替代 unescape() 并将图像保存为 base64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74160062/

相关文章:

html - 如何让内容(主要是图像)根据 tumblr 上的窗口大小缩放或调整大小?

html - 具有从阴影创建的边框的剪辑路径的边框半径

bash - 将 shell 脚本设置为 utf8

image - 将 Microsoft Paint 与 Matlab 代码结合使用

javascript - 我想使用 jquery mobile 显示 iphone 的 native 警告框

css - SVG <circle> 填充覆盖前一个圆

c# - 使用 .NET 如何将包含 Latin-1 重音字符的 ISO 8859-1 编码文本文件转换为 UTF-8

java - 如何将 Observable<byte[]> 转换为 Observable<String>?

image - 如何将背景图像淡化为透明?

javascript - 来自 d3.js html 的 getIntersectionList