ฉันต้องการแปลง SVG เป็นภาพบิตแมป (เช่น JPEG, PNG, ฯลฯ ) ผ่านทาง JavaScript
ฉันต้องการแปลง SVG เป็นภาพบิตแมป (เช่น JPEG, PNG, ฯลฯ ) ผ่านทาง JavaScript
คำตอบ:
นี่คือวิธีที่คุณสามารถทำได้ผ่าน JavaScript:
toImage()
และdownload()
สำหรับรูปภาพที่ดาวน์โหลดอัตโนมัติ
โซลูชัน jbeard4 ทำงานได้อย่างสวยงาม
ฉันใช้Raphael SketchPadเพื่อสร้าง SVG ลิงก์ไปยังไฟล์ในขั้นตอนที่ 1
สำหรับปุ่มบันทึก (id ของ svg คือ "editor", id ของ canvas คือ "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
แต่ jquery html () ฟังก์ชั่นไม่ได้เพิ่มแท็ก svg ดังนั้นรหัสนี้ใช้งานได้สำหรับฉัน แต่ฉันต้องการที่จะแก้ไข canvg อยู่เพื่อcanvg('canvas', '<svg>'+$("#editor").html()+'</svg>');
$(selector).html()
ให้ผู้ปกครองขององค์ประกอบsvgของคุณมันจะทำงาน
html()
ห่อหุ้มหรือสร้างsvg
แท็กหลักด้วยตนเอง- ซึ่งอาจมีคุณลักษณะที่คุณไม่ต้องทำด้วยแฮ็คนี้ เพียงใช้$(svg_elem)[0].outerHTML
ช่วยให้คุณได้แหล่งที่มาเต็มรูปแบบของ svg และเนื้อหา แค่พูดว่า ...
ดูเหมือนว่าจะใช้งานได้ในเบราว์เซอร์ส่วนใหญ่:
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()
วิธีแก้ปัญหาการแปลง SVG เป็น blob URL และ blob URL เป็นภาพ 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;
}
ฉันเขียน ES6 Class ซึ่งทำหน้าที่นี้
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;
}
}
นี่คือวิธีการใช้งาน
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.
});
หากคุณต้องการรุ่นของวานิลลา JavaScript คุณสามารถตรงไปที่เว็บไซต์ของ Babelและเปลี่ยนรหัสที่นั่น
นี่คือโซลูชันฝั่งเซิร์ฟเวอร์ซึ่งใช้ PhantomJS คุณสามารถใช้ JSONP เพื่อโทรข้ามโดเมนไปยังบริการรูปภาพได้:
https://github.com/vidalab/banquo-server
ตัวอย่างเช่น:
จากนั้นคุณสามารถแสดงภาพด้วยแท็ก img:
<img src="data:image/png;base64, [base64 data]"/>
มันทำงานผ่านเบราว์เซอร์
เปลี่ยนsvg
ให้ตรงกับองค์ประกอบของคุณ
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
ที่png
สามารถแปลงได้ขึ้นอยู่กับเงื่อนไข:
svg
อยู่ในรูปแบบเส้นทาง SVG (สตริง) :
new Path2D()
และตั้งsvg
เป็นพารามิเตอร์canvas.toDataURL()
src
ตัวอย่าง:
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;
โปรดทราบว่าPath2D
ไม่รองรับie
และรองรับบางส่วนในขอบ Polyfill แก้ปัญหาได้ที่:
https://github.com/nilzona/path2d-polyfill
svg
หยดและวาดบนผืนผ้าใบโดยใช้.drawImage()
:
คำอธิบายที่ดี: http://ramblings.mcpher.com/Home/excelquirks/gassnips/svgtopng
โปรดทราบว่าใน ie คุณจะได้รับข้อยกเว้นในระยะของ canvas.toDataURL (); เป็นเพราะ IE มีข้อ จำกัด ด้านความปลอดภัยที่สูงเกินไปและถือว่า Canvas เป็นแบบอ่านอย่างเดียวหลังจากวาดภาพที่นั่น เบราว์เซอร์อื่น ๆ ทั้งหมดจะ จำกัด เฉพาะในกรณีที่ภาพเป็นจุดกำเนิดข้าม
canvg
ไลบรารี JavaScript มันเป็นห้องสมุดแยก แต่มีฟังก์ชั่นที่มีประโยชน์ชอบ:
ctx.drawSvg(rawSvg);
var dataURL = canvas.toDataURL();
เมื่อเร็ว ๆ นี้ฉันค้นพบห้องสมุดติดตามภาพสองภาพสำหรับ JavaScript ซึ่งสามารถสร้างบิตแมปที่ยอมรับได้ทั้งขนาดและคุณภาพ ฉันกำลังพัฒนาไลบรารี JavaScript และ CLI นี้:
https://www.npmjs.com/package/svg-png-converter
ซึ่งจัดทำ API แบบครบวงจรสำหรับพวกเขาทั้งหมดรองรับเบราว์เซอร์และโหนดไม่ขึ้นอยู่กับ DOM และเครื่องมือบรรทัดคำสั่ง
สำหรับการแปลงโลโก้ / การ์ตูน / ภาพเหมือนมันทำงานได้ดี สำหรับภาพถ่าย / ความสมจริงปรับแต่งบางอย่างเป็นสิ่งจำเป็นเนื่องจากขนาดเอาต์พุตสามารถเติบโตได้มาก
มันมีสนามเด็กเล่นแม้ว่าตอนนี้ฉันกำลังใช้งานที่ดีกว่าใช้งานง่ายกว่าเนื่องจากมีการเพิ่มคุณสมบัติเพิ่มเติม:
https://cancerberosgx.github.io/demos/svg-png-converter/playground/#