我正在嘗試將 svg 轉換為 png,使用此處的代碼作為轉換的基礎。
請注意以下代碼(它已被縮短為僅與我稍后將描述的錯誤相關的代碼):
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()使用了該函式,但是它已棄用,我必須使用替代方法。根據檔案,我應該使用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。
所以,總結到目前為止:
原始代碼適用于英文和非英文字符,但使用了
unescape()已棄用的功能。所以我應該用別的東西。更新后的代碼不編碼也不解碼,在使用非英文字符時會導致例外。
現在,問題 1,我該怎么做才能使用base64從包含非英文字符的 svg 創建影像?
作為替代解決方案,我這樣做了
'data:image/svg xml;utf8,' svgData
基本上,我沒有使用base64,而是使用utf8。這作業得很好,但我不確定它是否是正確的解決方案。
那么,問題 2,使用utf8是一種常見的做法嗎?與base64相比,它有什么問題嗎?
謝謝你。
根據@RobertLongson 下面的評論,我將代碼更新為:
'data:image/svg xml;utf8,' encodeURIComponent(svgData)
這適用于包含英文和非英文字符的 svg 元素。
現在,問題 3,這是正確的嗎?
就基本問題道歉。我不熟悉這個。謝謝。
uj5u.com熱心網友回復:
在這個例子中,我試圖避免使用上述函式來轉換為 base64,而是使用FileReader和特別是readAsDataURL函式來回傳資料 URI。我知道回呼的代碼有點復雜,但它可以作業。
據我了解谷歌翻譯 トマト 翻譯成??。
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>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/520187.html
下一篇:邊界半徑只圓一個角
