簡體   English   中英

將內聯 SVG 轉換為 Base64 字符串

[英]Convert inline SVG to Base64 string

我想將內聯 SVG 圖像發送到 PHP 腳本以使用 Imagick 將其轉換為 PNG。 為此,我必須知道如何在內聯 SVG 上獲取 base64 字符串。 對於畫布對象,它是一個簡單的“.toDataURL()”,但這不適用於內聯 SVG,因為它不是元素的全局函數。

test = function(){
    var b64 = document.getElementById("svg").toDataURL();
    alert(b64);
}

http://jsfiddle.net/nikolang/ccx195qj/1/

但是如何為內聯 SVG 做呢?

使用XMLSerializer將 DOM 轉換為字符串

var s = new XMLSerializer().serializeToString(document.getElementById("svg"))

然后btoa可以將其轉換為 base64

var encodedData = window.btoa(s);

只需添加數據 URL 介紹,即data:image/svg+xml;base64,就可以了。

您可以按如下方式相對簡單地完成此操作。 簡短的版本是

  1. 制作一個不附加到 dom 的圖像
  2. 設置其大小以匹配源svg
  3. base64編碼源svg ,附加相關數據,設置img src
  4. 獲取canvas上下文; .drawImage圖像

    <script type="text/javascript"> window.onload = function() { paintSvgToCanvas(document.getElementById('source'), document.getElementById('tgt')); } function paintSvgToCanvas(uSvg, uCanvas) { var pbx = document.createElement('img'); pbx.style.width = uSvg.style.width; pbx.style.height = uSvg.style.height; pbx.src = 'data:image/svg+xml;base64,' + window.btoa(uSvg.outerHTML); uCanvas.getContext('2d').drawImage(pbx, 0, 0); } </script>

     <svg xmlns="http://www.w3.org/2000/svg" width="467" height="462" id="source"> <rect x="80" y="60" width="250" height="250" rx="20" style="fill:#ff0000; stroke:#000000;stroke-width:2px;" /> <rect x="140" y="120" width="250" height="250" rx="40" style="fill:#0000ff; stroke:#000000; stroke-width:2px; fill-opacity:0.7;" /> </svg> <canvas height="462px" width="467px" id="tgt"></canvas>

JSFiddle: https ://jsfiddle.net/oz3tjnk7/

我只是試圖收集和解釋關於這個問題的所有偉大的想法。 這適用於 Chrome 76 和 Firefox 68

var svgElement = document.getElementById('svgId');

// Create your own image
var img = document.createElement('img');

// Serialize the svg to string
var svgString = new XMLSerializer().serializeToString(svgElement);

// Remove any characters outside the Latin1 range
var decoded = unescape(encodeURIComponent(svgString));

// Now we can use btoa to convert the svg to base64
var base64 = btoa(decoded);

var imgSource = `data:image/svg+xml;base64,${base64}`;

img.setAttribute('src', imgSource);

我在使用基於 SVG 的平面圖編輯器時遇到了同樣的問題,在繪制平面圖后,我們必須保存它以備后用。 長話短說,代碼比說話好,這是對我有用的最終代碼:

async saveFloorplan() {
  const svgElem = document.querySelector('#svg-element');
  let xmlSource = new XMLSerializer().serializeToString(svgElem);

  if (!xmlSource.match(/^<svg[^>]+xmlns="http:\/\/www\.w3\.org\/2000\/svg"/)) {
    xmlSource = xmlSource.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
  }
  if (!xmlSource.match(/^<svg[^>]+"http:\/\/www\.w3\.org\/1999\/xlink"/)) {
    xmlSource = xmlSource.replace(/^<svg/, '<svg xmlns:xlink="http://www.w3.org/1999/xlink"');
  }
  // add xml declaration
  xmlSource = `<?xml version="1.0" standalone="no"?>\r\n${xmlSource}`;

  const svg64 = encodeURIComponent(xmlSource);
  const b64Start = 'data:image/svg+xml;charset=utf-8,';

  const imgEl = new Image();
  const image64 = b64Start + svg64;
  imgEl.src = image64;

  const blobResp = await fetch(imgEl.src);
  const blob = await blobResp.blob();

  const payload = {...}

  payload.fileExtension = 'svg';
  payload.fileSize = blob.size;

  const formData = new FormData();
  formData.append('file', blob);

  const uploaded = await api.uploadFile(formData);  
}

此行將執行轉換:

window.btoa($("svg").wrap("<div id='xyz'/>").parent().html());

確保選擇了正確的字符集/編碼!

// 1. get the element
let e = document.getElementById("svg");

// 2. get the string representation of the element
var s = new XMLSerializer().serializeToString(e);
// or 
var s = e.outerHTML;

// 3. convert the string to url
// convert to utf8
var url = "data:image/svg+xml;utf8," + encodeURIComponent(s);
// convert to base64
var url = "data:image/svg+xml;base64," + window.btoa(unescape(encodeURIComponent(s)));
// or
var url = "data:image/svg+xml;base64," + Buffer.from(s, "utf-8").toString("base64")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM