gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 04:21:45 28 4
gpt4 key购买 nike

我正在尝试将 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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com