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 相关文章推荐
js form 验证函数 当前比较流行的错误提示
Jun 23 Javascript
利用google提供的API(JavaScript接口)获取网站访问者IP地理位置的代码详解
Jul 24 Javascript
poshytip 基于jquery的 插件 主要用于显示微博人的图像和鼠标提示等
Oct 12 Javascript
Json实现异步请求提交评论无需跳转其他页面
Oct 11 Javascript
node网页分段渲染详解
Sep 05 Javascript
JavaScript实现图片懒加载(Lazyload)
Nov 28 Javascript
javascript实现多张图片左右无缝滚动效果
Mar 22 Javascript
Vue之Watcher源码解析(2)
Jul 19 Javascript
vue中使用codemirror的实例详解
Nov 01 Javascript
JS尾递归的实现方法及代码优化技巧
Jan 19 Javascript
vue实现简单的日历效果
Sep 24 Javascript
js 获取本周、上周、本月、上月、本季度、上季度的开始结束日期
Feb 01 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 防恶意刷新实现代码
2010/05/16 PHP
php实现微信模拟登陆、获取用户列表及群发消息功能示例
2017/06/28 PHP
laravel 5异常错误:FatalErrorException in Handler.php line 38的解决
2017/10/12 PHP
PHP命令空间namespace及use的用法小结
2017/11/27 PHP
PHPstorm激活码2020年5月13日亲测有效
2020/09/17 PHP
javascript基于jQuery的表格悬停变色/恢复,表格点击变色/恢复,点击行选Checkbox
2008/08/05 Javascript
JS上传图片前的限制包括(jpg jpg gif及大小高宽)等
2012/12/19 Javascript
Node.js的项目构建工具Grunt的安装与配置教程
2016/05/12 Javascript
javaScript事件机制兼容【详细整理】
2016/07/23 Javascript
vue构建单页面应用实战
2017/04/10 Javascript
ReactNative踩坑之配置调试端口的解决方法
2017/07/28 Javascript
微信小程序实现列表下拉刷新上拉加载
2020/07/29 Javascript
electron demo项目npm install安装失败的解决方法
2018/02/06 Javascript
VUE+Element UI实现简单的表格行内编辑效果的示例的代码
2018/10/31 Javascript
微信小程序位置授权处理方法
2019/06/13 Javascript
javascript中正则表达式语法详解
2020/08/07 Javascript
[02:38]DOTA2 夜魇暗潮2020活动介绍官方视频
2020/11/04 DOTA
[01:05:52]DOTA2-DPC中国联赛 正赛 Ehome vs Aster BO3 第一场 2月2日
2021/03/11 DOTA
Python 通过URL打开图片实例详解
2017/06/01 Python
使用pandas read_table读取csv文件的方法
2018/07/04 Python
Python上下文管理器用法及实例解析
2019/11/11 Python
python 实现线程之间的通信示例
2020/02/14 Python
使用html5+css3来实现slider切换效果告别javascript+css
2013/01/08 HTML / CSS
倩碧英国官网:Clinique英国
2018/08/10 全球购物
白俄罗斯女装和针织品网上商店:Presli.by
2019/10/13 全球购物
护理实习自我鉴定
2013/12/14 职场文书
消防器材管理制度
2014/01/28 职场文书
花店创业计划书范文
2014/02/07 职场文书
货车司机岗位职责
2014/03/18 职场文书
《闻一多先生的说和做》教学反思
2014/04/28 职场文书
政治学求职信
2014/06/03 职场文书
2014单位领导班子四风对照检查材料思想汇报
2014/09/25 职场文书
工程合作意向书范本
2015/05/09 职场文书
党员干部学习十八届五中全会精神心得体会
2016/01/05 职场文书
导游词之贵州织金洞
2019/10/12 职场文书
JVM入门之类加载与字节码技术(类加载与类的加载器)
2021/06/15 Java/Android