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 相关文章推荐
prototype与jquery下Ajax实现的差别
Sep 13 Javascript
JavaScript 学习历程和心得分享
Dec 12 Javascript
Chrome中JSON.parse的特殊实现
Jan 12 Javascript
setTimeout的延时为0时多个浏览器的区别
May 23 Javascript
node.js中的querystring.escape方法使用说明
Dec 10 Javascript
JavaScript判断浏览器类型的方法
Feb 10 Javascript
基于jQuery仿淘宝产品图片放大镜代码分享
Jun 23 Javascript
微信小程序 form组件详解
Oct 25 Javascript
使用JSON作为函数的参数的优缺点
Oct 27 Javascript
node.js 发布订阅模式的实例
Sep 10 Javascript
angularJS开发注意事项
May 26 Javascript
搭建基于express框架运行环境的方法步骤
Nov 15 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
window+nginx+php环境配置 附配置搭配说明
2010/12/29 PHP
PHP超级全局变量数组小结
2012/10/04 PHP
使用PHP备份MySQL和网站发送到邮箱实例代码
2013/11/28 PHP
PHP循环结构实例讲解
2014/02/10 PHP
ThinkPHP让分页保持搜索状态的方法
2014/07/02 PHP
如何使用php实现评委评分器
2015/07/31 PHP
Zend Framework动作助手FlashMessenger用法详解
2016/03/05 PHP
分析 JavaScript 中令人困惑的变量赋值
2007/08/13 Javascript
现代 JavaScript 开发编程风格Idiomatic.js指南中文版
2014/05/28 Javascript
你所不了解的javascript操作DOM的细节知识点(一)
2015/06/17 Javascript
js实现滚动条滚动到某个位置便自动定位某个tr
2021/01/20 Javascript
Bootstrap按钮下拉菜单组件详解
2016/05/10 Javascript
JS正则表达式验证账号、手机号、电话和邮箱是否合法
2017/03/08 Javascript
js实现手机发送验证码功能
2017/03/13 Javascript
微信小程序 首页制作简单实例
2017/04/07 Javascript
jquery中有哪些api jQuery主要API
2017/11/20 jQuery
vue.js使用v-model指令实现的数据双向绑定功能示例
2018/05/22 Javascript
基于vue中keep-alive缓存问题的解决方法
2018/09/21 Javascript
微信小程序全局变量功能与用法详解
2019/01/22 Javascript
Node.js 多线程完全指南总结
2019/03/27 Javascript
JavaScript Canvas编写炫彩的网页时钟
2019/10/16 Javascript
[01:48]完美圣典齐天大圣至宝宣传片
2016/12/17 DOTA
浅谈python正则的常用方法 覆盖范围70%以上
2018/03/14 Python
pandas数据框,统计某列数据对应的个数方法
2018/04/11 Python
python celery分布式任务队列的使用详解
2019/07/08 Python
Prometheus开发中间件Exporter过程详解
2020/11/30 Python
pandas将list数据拆分成行或列的实现
2020/12/13 Python
Feelunique德国官方网站:欧洲最大的在线美容零售商
2019/07/20 全球购物
毕业典礼演讲稿
2014/05/13 职场文书
教师求职信范文
2014/05/24 职场文书
服装设计专业求职信
2014/06/16 职场文书
房地产销售经理岗位职责
2015/02/02 职场文书
销售人员管理制度
2015/08/06 职场文书
课文《燕子》教学反思
2016/02/17 职场文书
oracle重置序列从0开始递增1
2022/02/28 Oracle
uniapp引入支付宝原生扫码插件步骤详解
2022/07/23 Javascript