可缩放svg转图片,三种方法简单直接明了

方案一:svg保存下载为图片,总体思路就是svg转码--->画在canvas上--->下载

第一种是使用serializer将获取的svg转换为字符串,然后通过encodeURIComponent()转码

var svg = document.getElementById('mainsvg') // 获取svg
var serializer = new XMLSerializer()
var toExport = svg.cloneNode(true); // 克隆
var bb = svg.getBBox(); // getBBox方法返回一个包含svg元素的最小矩形的坐标对象。 包含(x,y)、width、height 需要用来解决svg中的图超出边界时无法全部完整保存问题
toExport.setAttribute('viewBox', (bb.x-20) + ' ' + (bb.y-20) + ' ' + (bb.width+40) + ' ' + (bb.height+40)); // 重新设置svg目前的视口
toExport.setAttribute('width', bb.width); // 重新设置svg目前的宽度
toExport.setAttribute('height', bb.height); // 重新设置svg目前的高度

var source = '<?xml version="1.0" standalone="no"?>\r\n' + serializer.serializeToString(toExport)
var image.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source)

第二种是转为base64

var svg = document.getElementById('mainsvg')
// 这里一定要给svg设置这两个命名空间,包含了image 则也需要加上xmlns:xlink 否则浏览器会报错不能下载图片
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg")
svg.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink")
// 这里用来解决当svg中图超出边界时,需要全部完整保存下来的功能
var toExport = svg.cloneNode(true);
var bb = svg.getBBox();
toExport.setAttribute('viewBox', (bb.x-20) + ' ' + (bb.y-20) + ' ' + (bb.width+40) + ' ' + (bb.height+40));
toExport.setAttribute('width', bb.width);
toExport.setAttribute('height', bb.height);
// 转为base64 一定要加上unescape(encodeURIComponent,否则浏览器会报错
var imgsrc = 'data:image/svg+xml;base64,'+ window.btoa(unescape(encodeURIComponent(toExport.outerHTML)))

这两种随便哪一种转码都可以,然后画在canvas上下载即可

var canvas = document.createElement("canvas") // 定义画布
canvas.width = bb.width // 定义宽高为当前svg的大小
canvas.height = bb.height
var context = canvas.getContext("2d");
context.fillStyle = '#fff' // 把图画在canvas上背景为白色的矩形上
context.fillRect(0, 0, bb.width, bb.height)
var image = new Image;
image.src = imgsrc;
image.onload = function() {
    context.drawImage(image, 0, 0);
    var a = document.createElement("a"); // 定义a链接后自动下载
    a.download = "sample.png";
    a.href = canvas.toDataURL("image/png")
    a.click();
};

完整代码

        // 第一种
        var svg = document.getElementById('mainsvg')
        var serializer = new XMLSerializer()
        var toExport = svg.cloneNode(true);
        var bb = svg.getBBox();
        toExport.setAttribute('viewBox', (bb.x-20) + ' ' + (bb.y-20) + ' ' + (bb.width+40) + ' ' + (bb.height+40));
        toExport.setAttribute('width', bb.width);
        toExport.setAttribute('height', bb.height);
        var source = '<?xml version="1.0" standalone="no"?>\r\n' + serializer.serializeToString(toExport)
        var image = new Image
        image.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source)
        var canvas = document.createElement("canvas")
        canvas.width = bb.width
        canvas.height = bb.height
        var context = canvas.getContext("2d")
        context.fillStyle = '#fff'
        context.fillRect(0, 0, bb.width, bb.height)
        image.onload = function () {
          context.drawImage(image, 0, 0)
          var a = document.createElement("a")
          a.download = "graph.png"
          a.href = canvas.toDataURL("image/png")
          a.click()
        }
        
        // 第二种    
        svg.setAttribute("xmlns", "http://www.w3.org/2000/svg")
        svg.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink")
        var toExport = svg.cloneNode(true);
        var bb = svg.getBBox();
        toExport.setAttribute('viewBox', (bb.x-20) + ' ' + (bb.y-20) + ' ' + (bb.width+40) + ' ' + (bb.height+40));
        toExport.setAttribute('width', bb.width);
        toExport.setAttribute('height', bb.height);
        var imgsrc = 'data:image/svg+xml;base64,'+ window.btoa(unescape(encodeURIComponent(toExport.outerHTML)))
        var canvas = document.createElement("canvas")
        canvas.width = bb.width
        canvas.height = bb.height
        var context = canvas.getContext("2d");
        context.fillStyle = '#fff'
        context.fillRect(0, 0, bb.width, bb.height)
        var image = new Image;
        image.src = imgsrc;
        image.onload = function() {
          context.drawImage(image, 0, 0);
          var a = document.createElement("a");
          a.download = "sample.png";
          a.href = canvas.toDataURL("image/png")
          a.click();
        };

方案二:使用插件saveSvgAsPng  也是最简单直接的

按照官网的提示,一步步操作。

github:https://github.com/exupero/saveSvgAsPng

翻译版本:https://www.helplib.com/GitHub/article_110596

1.用npm把插件装上

npm install save-svg-as-png

2.在需要使用的vue文件中把js文件import进来

import saveSvg from 'save-svg-as-png'

3.直接调用函数下载即可,还有各种方法可调用

handleImg() {
    var svg = document.getElementById('mainsvg')
    saveSvg.saveSvgAsPng(svg, 'graph.png')
    // 还可以加上各种样式参数
    // saveSvg.saveSvgAsPng(svg, 'graph.png', {backgroundColor: 'white', width:bb.width+60, height: bb.height+60, left: bb.x-40, top: bb.y-40})

}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值