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 相关文章推荐
模拟用户操作Input元素,不会触发相应事件
May 11 Javascript
jQuery的实现原理的模拟代码 -5 Ajax
Aug 07 Javascript
Javascript this 的一些学习总结
Aug 02 Javascript
简单的ajax连接库分享(不用jquery的ajax)
Jan 19 Javascript
jQuery中offsetParent()方法用法实例
Jan 19 Javascript
JS将滑动门改为选项卡(需鼠标点击)的实现方法
Sep 27 Javascript
微信小程序实现tab和swiper切换结合效果
Jul 17 Javascript
vue.js实现的绑定class操作示例
Jul 06 Javascript
微信小程序实现单选功能
Oct 30 Javascript
JS数组去重的6种方法完整实例
Dec 08 Javascript
node.js中fs文件系统模块的使用方法实例详解
Feb 13 Javascript
浅谈js中的attributes和Attribute的用法与区别
Jul 16 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中uploaded_files函数使用方法详解
2011/03/09 PHP
php报表之jpgraph柱状图实例代码
2011/08/22 PHP
php木马webshell扫描器代码
2012/01/25 PHP
PHP 万年历实现代码
2012/10/18 PHP
php删除数组元素示例分享
2014/02/17 PHP
PHP图片处理之图片旋转和图片翻转实例
2014/11/19 PHP
PHP+redis实现添加处理投票的方法
2015/11/14 PHP
PHP邮箱验证示例教程
2016/06/01 PHP
javascript demo 基本技巧
2009/12/18 Javascript
JS脚本defer的作用示例介绍
2014/01/02 Javascript
js showModalDialog 弹出对话框的简单实例(子窗体)
2014/01/07 Javascript
js 实现的可折叠留言板(附源码下载)
2014/07/01 Javascript
中文输入法不触发onkeyup事件的解决办法
2014/07/09 Javascript
原生JavaScript实现合并多个数组示例
2014/09/21 Javascript
创建js对象和js类的方法汇总
2014/12/24 Javascript
js实现分享到随页面滚动而滑动效果的方法
2015/04/10 Javascript
Angularjs实现mvvm式的选项卡示例代码
2016/09/08 Javascript
AngularJS 在同一个界面启动多个ng-app应用模块详解
2016/12/20 Javascript
React Native 截屏组件的示例代码
2017/12/06 Javascript
angular2中使用第三方js库的实例
2018/02/26 Javascript
浅探express路由和中间件的实现
2019/09/30 Javascript
vant IndexBar实现的城市列表的示例代码
2019/11/20 Javascript
vue在响应头response中获取自定义headers操作
2020/07/24 Javascript
urllib和BeautifulSoup爬取维基百科的词条简单实例
2018/01/17 Python
Python数据分析之双色球统计两个红和蓝球哪组合比例高的方法
2018/02/03 Python
python 定时器,轮询定时器的实例
2019/02/20 Python
python读取并定位excel数据坐标系详解
2019/06/26 Python
Django密码系统实现过程详解
2019/07/19 Python
解决python 读取excel时 日期变成数字并加.0的问题
2019/10/08 Python
Python3.x+迅雷x 自动下载高分电影的实现方法
2020/01/12 Python
使用Python脚本从文件读取数据代码实例
2020/01/19 Python
TensorFlow低版本代码自动升级为1.0版本
2021/02/20 Python
详解html2canvas截图不能截取圆角图片的解决方案
2018/01/30 HTML / CSS
台湾租车首选品牌:IWS艾维士租车
2019/05/03 全球购物
Vuori官网:运动服装的终级表现
2021/01/27 全球购物
招聘单位介绍信
2014/01/14 职场文书