Chcę przekonwertować SVG na obrazy bitmapowe (takie jak JPEG, PNG itp.) Za pomocą JavaScript.
Chcę przekonwertować SVG na obrazy bitmapowe (takie jak JPEG, PNG itp.) Za pomocą JavaScript.
Odpowiedzi:
Oto, jak możesz to zrobić za pomocą JavaScript:
toImage()
i także download()
dla automatycznie pobranego obrazu.
Rozwiązanie jbeard4 działało pięknie.
Korzystam z programu Raphael SketchPad, aby utworzyć plik SVG. Link do plików w kroku 1.
W przypadku przycisku Zapisz (identyfikator svg to „edytor”, identyfikator płótna to „canvas”):
$("#editor_save").click(function() {
// the canvg call that takes the svg xml and converts it to a canvas
canvg('canvas', $("#editor").html());
// the canvas calls to output a png
var canvas = document.getElementById("canvas");
var img = canvas.toDataURL("image/png");
// do what you want with the base64, write to screen, post to server, etc...
});
<svg>...</svg
ale funkcja hquml () jquery nie dodaje tagu svg, więc ten kod działa dla mnie, ale musiałem edytować live canvg docanvg('canvas', '<svg>'+$("#editor").html()+'</svg>');
$(selector).html()
do rodzica elementu svg , zadziała
html()
na opakowaniach ani ręcznie konstruować svg
tagu nadrzędnego - który może nawet mieć atrybuty, które pomijasz podczas tego włamania. Wystarczy użyć $(svg_elem)[0].outerHTML
daje pełne źródło svg i jego zawartość. Tylko mówię ...
Wydaje się, że działa to w większości przeglądarek:
function copyStylesInline(destinationNode, sourceNode) {
var containerElements = ["svg","g"];
for (var cd = 0; cd < destinationNode.childNodes.length; cd++) {
var child = destinationNode.childNodes[cd];
if (containerElements.indexOf(child.tagName) != -1) {
copyStylesInline(child, sourceNode.childNodes[cd]);
continue;
}
var style = sourceNode.childNodes[cd].currentStyle || window.getComputedStyle(sourceNode.childNodes[cd]);
if (style == "undefined" || style == null) continue;
for (var st = 0; st < style.length; st++){
child.style.setProperty(style[st], style.getPropertyValue(style[st]));
}
}
}
function triggerDownload (imgURI, fileName) {
var evt = new MouseEvent("click", {
view: window,
bubbles: false,
cancelable: true
});
var a = document.createElement("a");
a.setAttribute("download", fileName);
a.setAttribute("href", imgURI);
a.setAttribute("target", '_blank');
a.dispatchEvent(evt);
}
function downloadSvg(svg, fileName) {
var copy = svg.cloneNode(true);
copyStylesInline(copy, svg);
var canvas = document.createElement("canvas");
var bbox = svg.getBBox();
canvas.width = bbox.width;
canvas.height = bbox.height;
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, bbox.width, bbox.height);
var data = (new XMLSerializer()).serializeToString(copy);
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svgBlob = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svgBlob);
img.onload = function () {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob)
{
var blob = canvas.msToBlob();
navigator.msSaveOrOpenBlob(blob, fileName);
}
else {
var imgURI = canvas
.toDataURL("image/png")
.replace("image/png", "image/octet-stream");
triggerDownload(imgURI, fileName);
}
document.removeChild(canvas);
};
img.src = url;
}
.msToBlob()
Rozwiązanie do konwersji SVG na URL obiektu blob i URL obiektu blob do obrazu png
const svg=`<svg version="1.1" baseProfile="full" width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text></svg>`
svgToPng(svg,(imgData)=>{
const pngImage = document.createElement('img');
document.body.appendChild(pngImage);
pngImage.src=imgData;
});
function svgToPng(svg, callback) {
const url = getSvgUrl(svg);
svgUrlToPng(url, (imgData) => {
callback(imgData);
URL.revokeObjectURL(url);
});
}
function getSvgUrl(svg) {
return URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' }));
}
function svgUrlToPng(svgUrl, callback) {
const svgImage = document.createElement('img');
// imgPreview.style.position = 'absolute';
// imgPreview.style.top = '-9999px';
document.body.appendChild(svgImage);
svgImage.onload = function () {
const canvas = document.createElement('canvas');
canvas.width = svgImage.clientWidth;
canvas.height = svgImage.clientHeight;
const canvasCtx = canvas.getContext('2d');
canvasCtx.drawImage(svgImage, 0, 0);
const imgData = canvas.toDataURL('image/png');
callback(imgData);
// document.body.removeChild(imgPreview);
};
svgImage.src = svgUrl;
}
Napisałem tę klasę ES6, która wykonuje zadanie.
class SvgToPngConverter {
constructor() {
this._init = this._init.bind(this);
this._cleanUp = this._cleanUp.bind(this);
this.convertFromInput = this.convertFromInput.bind(this);
}
_init() {
this.canvas = document.createElement("canvas");
this.imgPreview = document.createElement("img");
this.imgPreview.style = "position: absolute; top: -9999px";
document.body.appendChild(this.imgPreview);
this.canvasCtx = this.canvas.getContext("2d");
}
_cleanUp() {
document.body.removeChild(this.imgPreview);
}
convertFromInput(input, callback) {
this._init();
let _this = this;
this.imgPreview.onload = function() {
const img = new Image();
_this.canvas.width = _this.imgPreview.clientWidth;
_this.canvas.height = _this.imgPreview.clientHeight;
img.crossOrigin = "anonymous";
img.src = _this.imgPreview.src;
img.onload = function() {
_this.canvasCtx.drawImage(img, 0, 0);
let imgData = _this.canvas.toDataURL("image/png");
if(typeof callback == "function"){
callback(imgData)
}
_this._cleanUp();
};
};
this.imgPreview.src = input;
}
}
Oto jak z niego korzystasz
let input = "https://restcountries.eu/data/afg.svg"
new SvgToPngConverter().convertFromInput(input, function(imgData){
// You now have your png data in base64 (imgData).
// Do what ever you wish with it here.
});
Jeśli chcesz waniliową wersję JavaScript, możesz udać się na stronę Babel i tam przetransportować kod.
Oto rozwiązanie po stronie serwera oparte na PhantomJS. Możesz użyć JSONP do wykonania połączenia między domenami do usługi obrazu:
https://github.com/vidalab/banquo-server
Na przykład:
Następnie możesz wyświetlić obraz z tagiem img:
<img src="data:image/png;base64, [base64 data]"/>
Działa w różnych przeglądarkach.
zmień, svg
aby dopasować swój element
function svg2img(){
var svg = document.querySelector('svg');
var xml = new XMLSerializer().serializeToString(svg);
var svg64 = btoa(xml); //for utf8: btoa(unescape(encodeURIComponent(xml)))
var b64start = 'data:image/svg+xml;base64,';
var image64 = b64start + svg64;
return image64;
};svg2img()
Uncaught TypeError: Failed to execute 'serializeToString' on 'XMLSerializer': parameter 1 is not of type 'Node'.
Svg
do png
konwersji w zależności od warunków:
svg
jest w formacie ścieżki SVG (ciąg) :
new Path2D()
i ustaw svg
jako parametrcanvas.toDataURL()
jako src
.przykład:
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
let svgText = 'M10 10 h 80 v 80 h -80 Z';
let p = new Path2D('M10 10 h 80 v 80 h -80 Z');
ctx.stroke(p);
let url = canvas.toDataURL();
const img = new Image();
img.src = url;
Zauważ, że Path2D
nie obsługiwane ie
i częściowo obsługiwane w Edge. Polyfill rozwiązuje to:
https://github.com/nilzona/path2d-polyfill
svg
kroplę i narysuj na płótnie, używając .drawImage()
:
Ładny opis: http://ramblings.mcpher.com/Home/excelquirks/gassnips/svgtopng
Zauważ, że np. Otrzymasz wyjątek na etapie canvas.toDataURL (); Jest tak, ponieważ IE ma zbyt wysokie ograniczenia bezpieczeństwa i traktuje płótno jako tylko do odczytu po narysowaniu tam obrazu. Wszystkie inne przeglądarki ograniczają tylko wtedy, gdy obraz ma pochodzenie krzyżowe.
canvg
biblioteki JavaScript. Jest to osobna biblioteka, ale ma przydatne funkcje.Lubić:
ctx.drawSvg(rawSvg);
var dataURL = canvas.toDataURL();
Niedawno odkryłem kilka bibliotek śledzenia obrazów dla JavaScript, które rzeczywiście są w stanie stworzyć akceptowalne przybliżenie mapy bitowej, zarówno pod względem wielkości, jak i jakości. Tworzę tę bibliotekę JavaScript i interfejs CLI:
https://www.npmjs.com/package/svg-png-converter
Który zapewnia ujednolicony interfejs API dla wszystkich, obsługujący przeglądarkę i węzeł, w zależności od modelu DOM, oraz narzędzie wiersza poleceń.
Do konwersji logo / kreskówek / podobnych obrazów wykonuje doskonałą robotę. W przypadku zdjęć / realizmu potrzebne są pewne poprawki, ponieważ rozmiar wyjściowy może znacznie wzrosnąć.
Ma plac zabaw, chociaż teraz pracuję nad lepszym, łatwiejszym w użyciu, ponieważ dodano więcej funkcji:
https://cancerberosgx.github.io/demos/svg-png-converter/playground/#