JavaScript 下载svg图片为png格式


Posted in Javascript onJune 21, 2018

1.遇到需要将svg下载的需求,网上找了一些代码,地址是这个https://github.com/exupero/saveSvgAsPng,但是不太好用,莫名的把网页所有的svg都下载了,于是在源码的基础上做了一些小的修改;代码如下所示

var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [<!ENTITY nbsp " ">]>'; 
function convertToPng(src, w, h) { 
      var canvas = document.createElement('canvas'); 
      var context = canvas.getContext('2d'); 
      canvas.width = w; 
      canvas.height = h; 
      context.drawImage(src, 0, 0); 
      var png; 
      try { 
        png = canvas.toDataURL("image/png"); 
      } catch (e) { 
        if ((typeof SecurityError !== 'undefined' && e instanceof SecurityError) || e.name == "SecurityError") { 
          console.error("Rendered SVG images cannot be downloaded in this browser."); 
          return; 
        } else { 
          throw e; 
        } 
      } 
      return png; 
    } 
    function isElement(obj) { 
      return obj instanceof HTMLElement || obj instanceof SVGElement; 
    } 
    function reEncode(data) { 
      data = encodeURIComponent(data); 
      data = data.replace(/%([0-9A-F]{2})/g, function (match, p1) { 
        var c = String.fromCharCode('0x' + p1); 
        return c === '%' ? '%25' : c; 
      }); 
      return decodeURIComponent(data); 
    } 
    function uriToBlob(uri) { 
      var byteString = window.atob(uri.split(',')[1]); 
      var mimeString = uri.split(',')[0].split(':')[1].split(';')[0] 
      var buffer = new ArrayBuffer(byteString.length); 
      var intArray = new Uint8Array(buffer); 
      for (var i = 0; i < byteString.length; i++) { 
        intArray[i] = byteString.charCodeAt(i); 
      } 
      return new Blob([buffer], {type: mimeString}); 
    } 
    function downLoad(el, name) { 
      if (!isElement(el)) { 
        throw new Error('an HTMLElement or SVGElement is required; got ' + el); 
      } 
      if (!name) { 
        console.error("文件名为空!"); 
        return; 
      } 
      var xmlns = "http://www.w3.org/2000/xmlns/"; 
      var clone = el.cloneNode(true); 
      clone.setAttribute("version", "1.1"); 
      if (!clone.getAttribute('xmlns')) { 
        clone.setAttributeNS(xmlns, "xmlns", "http://www.w3.org/2000/svg"); 
      } 
      if (!clone.getAttribute('xmlns:xlink')) { 
        clone.setAttributeNS(xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink"); 
      } 
      var svg = clone.outerHTML; 
      var uri = 'data:image/svg+xml;base64,' + window.btoa(reEncode(doctype + svg)); 
      var image = new Image(); 
      image.onload = function () { 
        var png = convertToPng(image, image.width, image.height); 
        var saveLink = document.createElement('a'); 
        var downloadSupported = 'download' in saveLink; 
        if (downloadSupported) { 
          saveLink.download = name + ".png"; 
          saveLink.style.display = 'none'; 
          document.body.appendChild(saveLink); 
          try { 
            var blob = uriToBlob(png); 
            var url = URL.createObjectURL(blob); 
            saveLink.href = url; 
            saveLink.onclick = function () { 
              requestAnimationFrame(function () { 
                URL.revokeObjectURL(url); 
              }) 
            }; 
          } catch (e) { 
            saveLink.href = uri; 
          } 
          saveLink.click(); 
          document.body.removeChild(saveLink); 
        } 
      }; 
      image.src = uri; 
    }

这里使用的时候只需要调用download方法就可以了,建议封装成一个单独的下载服务;download方法的第一个参数el指的是dom元素,就是svg元素,具体的获取方法通过js或者d3的选择器都可以;例如

<div id="svg-parent-div"><svg>...</svg></div>

一般通过获取svg的父元素来找到它,比如

var el = d3.select("#svg-parent-div").node().children[0]; 
download(el,"下载图片");

这样就可以了;

代码对于svg的没设置命名空间的情况做了处理,通过如下代码,如果svg 元素没有 设置命名空间,则添加; 

el.setAttributeNS(xmlns, "xmlns", "http://www.w3.org/2000/svg"); 
el.setAttributeNS(xmlns, "xmlns:xlink", "http://www.w3.org/1999/xlink");

同时,添加的命名空间作用在clone的元素上,不会影响原来的svg元素;

总结

以上所述是小编给大家介绍的JavaScript 下载svg图片为png格式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery JSON的解析方式分享
Apr 05 Javascript
jQuery fadeTo方法调整图片的透明度使用介绍
May 06 Javascript
jQuery中prepend()方法用法实例
Dec 25 Javascript
jQuery中eq()方法用法实例
Jan 05 Javascript
原生js和jQuery写的网页选项卡特效对比
Apr 27 Javascript
jQuery中 delegate使用的问题
Jul 03 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
Jul 22 Javascript
JS中的==运算: [''] == false —&gt;true
Jul 24 Javascript
自定义vue组件发布到npm的方法
May 09 Javascript
详解vue微信网页授权最终解决方案
Jun 16 Javascript
JavaScript常用工具函数大全
May 06 Javascript
openlayers4实现点动态扩散
Aug 17 Javascript
MVVM 双向绑定的实现代码
Jun 21 #Javascript
在vue2.0中引用element-ui组件库的方法
Jun 21 #Javascript
vue树形结构获取键值的方法示例
Jun 21 #Javascript
vue使用jsonp抓取qq音乐数据的方法
Jun 21 #Javascript
Vue 获取数组键名的方法
Jun 21 #Javascript
Taro集成Redux快速上手的方法示例
Jun 21 #Javascript
vue2.0项目实现路由跳转的方法详解
Jun 21 #Javascript
You might like
php cookie 登录验证示例代码
2009/03/16 PHP
PHP在线生成二维码(google api)的实现代码详解
2013/06/04 PHP
php面向对象与面向过程两种方法给图片添加文字水印
2015/08/26 PHP
javascript new 需不需要继续使用
2009/07/02 Javascript
JQuery的Alert消息框插件使用介绍
2010/10/09 Javascript
理解Javascript_08_函数对象
2010/10/15 Javascript
javascript模拟的Ping效果代码 (Web Ping)
2011/03/13 Javascript
自定义jQuery选项卡插件实例
2013/03/27 Javascript
jquery 使用简明教程
2014/03/05 Javascript
JavaScript 匿名函数和闭包介绍
2015/04/13 Javascript
AngularJS bootstrap启动详解及实例代码
2016/09/14 Javascript
js模糊查询实例分享
2016/12/26 Javascript
Vue.js 2.0 移动端拍照压缩图片上传预览功能
2017/03/06 Javascript
VUEJS 2.0 子组件访问/调用父组件的实例
2018/02/10 Javascript
JavaScript实现小球沿正弦曲线运动
2020/09/07 Javascript
微信小程序自定义弹出层效果
2020/05/26 Javascript
NodeJS模块Buffer原理及使用方法解析
2020/11/11 NodeJs
python使用beautifulsoup从爱奇艺网抓取视频播放
2014/01/23 Python
Python with的用法
2014/08/22 Python
TF-IDF与余弦相似性的应用(一) 自动提取关键词
2017/12/21 Python
Python图形绘制操作之正弦曲线实现方法分析
2017/12/25 Python
Python 实现删除某路径下文件及文件夹的实例讲解
2018/04/24 Python
在pycharm中python切换解释器失败的解决方法
2018/10/29 Python
python实现K近邻回归,采用等权重和不等权重的方法
2019/01/23 Python
python单例模式的多种实现方法
2019/07/26 Python
python处理RSTP视频流过程解析
2020/01/11 Python
Python基于smtplib模块发送邮件代码实例
2020/05/29 Python
Python根据指定文件生成XML的方法
2020/06/29 Python
会计实习期自我鉴定
2013/10/06 职场文书
大学生求职简历的自我评价范文
2013/10/12 职场文书
法学个人求职信范文
2014/01/27 职场文书
幼儿园教学管理制度
2014/02/04 职场文书
职工运动会感言
2014/02/07 职场文书
家庭聚会祝酒词
2015/08/11 职场文书
导游词之云南丽江-泸沽湖
2019/09/26 职场文书
Win11绿屏怎么办?Win11绿屏死机的解决方法
2021/11/21 数码科技