在使用svg进行图形绘制之后,可能需要下载已经绘制的svg图片,我们可能会遇到以下两种情况:
情况1:
<svg width="640" height="400" xmlns="http://www.w3.org/2000/svg" id="svgColumn">
<text x="200" y="20" font-size="20">SVG 华东地区手机12个月的数据 柱状图</text>
<line x1="20" y1="380" x2="620" y2="380" stroke="black" stroke-width="1.5" />
<line x1="20" y1="380" x2="20" y2="1" style="stroke: black; stroke-width: 1.5" />
<path d="M600 360 L620 380 L600 400 Z" style="stroke: black; stroke-width: 1" />
<path d="M1 20 L20 1 L40 20 Z" style="stroke: black; stroke-width: 1" />
</svg>
情况2:
<svg width="640" height="400" xmlns="http://www.w3.org/2000/svg" id="svgColumn">
<text x="200" y="20" font-size="20">SVG 华东地区手机12个月的数据 柱状图</text>
<line x1="20" y1="380" x2="620" y2="380" stroke="black" stroke-width="1.5" />
<line x1="20" y1="380" x2="20" y2="1" style="stroke: black; stroke-width: 1.5" />
<path d="M600 360 L620 380 L600 400 Z" style="stroke: black; stroke-width: 1" />
<path d="M1 20 L20 1 L40 20 Z" style="stroke: black; stroke-width: 1" />
<image id="demoImg" width="250" href="./2ad33d6ed244630e8526343c390156e5.jpeg">
</image>
</svg>
第一种是svg内部都是使用svg的方法进行绘制的,我们可以直接通过canvas的方法进行绘制下载,方法如下
let downEle = document.getElementById(`download`);
downEle.addEventListener("click", function () {
downloadpng();
})
function downloadpng() {
let rootNode = document.getElementById(`svgColumn`);
var serializer = new XMLSerializer();
var source =
'<?xml version="1.0" standalone="no"?>\r\n' +
serializer.serializeToString(rootNode);
var image = new Image();
image.src =
"data:image/svg+xml;charset=utf-8," + encodeURIComponent(source);
image.onload = () => {
var canvas = document.createElement("canvas");
canvas.width = 640;
canvas.height = 500;
var context = canvas.getContext("2d");
context.fillStyle = "#fff"; //设置背景
context.fillRect(0, 0, 640, 500);
context.drawImage(image, 0, 0, 640, 500, 0, 0, 640, 500); //进行绘制图片
var url = canvas.toDataURL("image/jpeg"); // 这就是得到的base64编码
var pngName = `${this.phaseId}`;
var a = document.createElement("a");
a.download = '测试名字' + ".jpeg";
a.href = url;
a.click();
};
}
第二种情况是在svg内部嵌套了一个image的图片,此时则无法使用第一种方法直接进行下载,下载的图片无内嵌图片,后来通过调查发下,需要把image引入的图片的路径更改微base64的方法后,再进行下载则可以实现,并解决问题。方法如下。
let newImgUrl = ''
//图片转化base64
const toBase64 = (img) => {
var canvas = document.createElement("canvas");
canvas.width = 250;
canvas.height = 250;
var context = canvas.getContext("2d");
context.fillStyle = "#fff"; // 设置保存后的PNG 是白色的
context.fillRect(0, 0, 250, 250);
context.drawImage(img, 0, 0, 250, 250); //进行绘制图片
var url = canvas.toDataURL("image/jpeg"); // 这就是得到的base64编码
newImgUrl = url;
console.log(newImgUrl,'newImgUrlnewImgUrl')
var demoImg = document.getElementById("demoImg");
demoImg.setAttribute("href",newImgUrl)
}
//传入路径转化成图片
const getImageUrlBase64 = (url) => {
const img = new Image();
img.crossOrigin = 'anonymous';//处理跨域,后端也要设置跨域处理才行
img.src = url;
img.onload = () => {
toBase64(img);
}
}
getImageUrlBase64("./2ad33d6ed244630e8526343c390156e5.jpeg") //传入需要更改的路径
通过此种方法就可以解决svg内部嵌套image图片下载异常的问题了。
完成的html例子如下,本地调试的话,可以把html文件单独放在文件夹内,内嵌一张自己的图片,打开vscode 使用 Open with live server插件即可进行调试使用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<svg width="640" height="400" xmlns="http://www.w3.org/2000/svg" id="svgColumn">
<text x="200" y="20" font-size="20">SVG 华东地区手机12个月的数据 柱状图</text>
<line x1="20" y1="380" x2="620" y2="380" stroke="black" stroke-width="1.5" />
<line x1="20" y1="380" x2="20" y2="1" style="stroke: black; stroke-width: 1.5" />
<path d="M600 360 L620 380 L600 400 Z" style="stroke: black; stroke-width: 1" />
<path d="M1 20 L20 1 L40 20 Z" style="stroke: black; stroke-width: 1" />
<image id="demoImg" width="250" href="./2ad33d6ed244630e8526343c390156e5.jpeg">
</image>
</svg>
<button id="download">下载按钮</button>
</body>
<script>
let downEle = document.getElementById(`download`);
downEle.addEventListener("click", function () {
downloadpng();
})
function downloadpng() {
let rootNode = document.getElementById(`svgColumn`);
var serializer = new XMLSerializer();
var source =
'<?xml version="1.0" standalone="no"?>\r\n' +
serializer.serializeToString(rootNode);
var image = new Image();
image.src =
"data:image/svg+xml;charset=utf-8," + encodeURIComponent(source);
image.onload = () => {
var canvas = document.createElement("canvas");
canvas.width = 640;
canvas.height = 500;
var context = canvas.getContext("2d");
context.fillStyle = "#fff"; //设置背景
context.fillRect(0, 0, 640, 500);
context.drawImage(image, 0, 0, 640, 500, 0, 0, 640, 500); //进行绘制图片
var url = canvas.toDataURL("image/jpeg"); // 这就是得到的base64编码
var pngName = `${this.phaseId}`;
var a = document.createElement("a");
a.download = '测试名字' + ".jpeg";
a.href = url;
a.click();
};
}
let newImgUrl = ''
//图片转化base64
const toBase64 = (img) => {
var canvas = document.createElement("canvas");
canvas.width = 250;
canvas.height = 250;
var context = canvas.getContext("2d");
context.fillStyle = "#fff"; // 设置保存后的PNG 是白色的
context.fillRect(0, 0, 250, 250);
context.drawImage(img, 0, 0, 250, 250); //进行绘制图片
var url = canvas.toDataURL("image/jpeg"); // 这就是得到的base64编码
newImgUrl = url;
console.log(newImgUrl,'newImgUrlnewImgUrl')
var demoImg = document.getElementById("demoImg");
demoImg.setAttribute("href",newImgUrl)
}
//传入路径转化成图片
const getImageUrlBase64 = (url) => {
const img = new Image();
img.crossOrigin = 'anonymous';//处理跨域,后端也要设置跨域处理才行
img.src = url;
img.onload = () => {
toBase64(img);
}
}
getImageUrlBase64("./2ad33d6ed244630e8526343c390156e5.jpeg") //传入需要更改的路径
</script>
</html>
文件夹截图:
效果图:
下载的效果图:
如有问题请评论沟通