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 相关文章推荐
JQuyer $.post 与 $.ajax 访问WCF ajax service 时的问题需要注意的地方
Sep 20 Javascript
JavaScript charCodeAt方法入门实例(用于取得指定位置字符的Unicode编码)
Oct 17 Javascript
JavaScript对象反射用法实例
Apr 17 Javascript
表单验证正则表达式实例代码详解
Nov 09 Javascript
基于jQuery实现音乐播放试听列表
Apr 14 Javascript
基于BootStrap Metronic开发框架经验小结【四】Bootstrap图标的提取和利用
May 12 Javascript
js Canvas绘制圆形时钟效果
Feb 17 Javascript
js移动端事件基础及常用事件库详解
Aug 15 Javascript
深入研究jQuery图片懒加载 lazyload.js使用方法
Aug 16 jQuery
详解JSONObject和JSONArray区别及基本用法
Oct 25 Javascript
浅入深出Vue之组件使用
Jul 11 Javascript
基于VUE实现判断设备是PC还是移动端
Jul 03 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函数获取当前运行的环境 来进行判断执行逻辑(小技巧)
2013/06/25 PHP
php 判断服务器操作系统的类型
2014/02/17 PHP
PHP一致性hash分布式算法封装类定义与用法示例
2018/08/04 PHP
php使用goto实现自动重启swoole、reactphp、workerman服务的代码
2020/04/13 PHP
超级兔子让浮动层消失的前因后果
2007/03/09 Javascript
Javascript中arguments和arguments.callee的区别浅析
2015/04/24 Javascript
jQuery实现在列表的首行添加数据
2015/05/19 Javascript
JavaScript中的对象和原型(一)
2016/08/12 Javascript
浅析vue数据绑定
2017/01/17 Javascript
Nodejs 获取时间加手机标识的32位标识实现代码
2017/03/07 NodeJs
JS判断数组那点事
2017/10/10 Javascript
详解redux异步操作实践
2018/08/15 Javascript
简述vue状态管理模式之vuex
2018/08/29 Javascript
vue中$nextTick的用法讲解
2019/01/17 Javascript
vue-cli3 项目从搭建优化到docker部署的方法
2019/01/28 Javascript
JS实现纵向轮播图(初级版)
2020/01/18 Javascript
uniapp微信小程序实现一个页面多个倒计时
2020/11/01 Javascript
python3.3实现乘法表示例
2014/02/07 Python
Python自动连接ssh的方法
2015/03/07 Python
浅谈Python处理PDF的方法
2017/11/10 Python
matplotlib在python上绘制3D散点图实例详解
2017/12/09 Python
pygame实现俄罗斯方块游戏(AI篇2)
2019/10/29 Python
opencv3/C++实现视频背景去除建模(BSM)
2019/12/11 Python
Django模板获取field的verbose_name实例
2020/05/19 Python
Python selenium键盘鼠标事件实现过程详解
2020/07/28 Python
python中通过pip安装库文件时出现“EnvironmentError: [WinError 5] 拒绝访问”的问题及解决方案
2020/08/11 Python
python删除文件、清空目录的实现方法
2020/09/23 Python
非凡女性奢华谦虚风格:The Modist
2017/10/28 全球购物
摩托车和ATV零件、配件和服装的首选在线零售商:MotoSport
2017/12/22 全球购物
FLOS美国官网:意大利高级照明工艺的传奇
2018/08/07 全球购物
求职推荐信范文
2013/12/01 职场文书
会计电算化专业毕业生推荐信
2013/12/24 职场文书
护士感人事迹
2014/05/01 职场文书
岗位标兵事迹材料
2014/05/17 职场文书
2014年组织部工作总结
2014/11/14 职场文书
pytorch 梯度NAN异常值的解决方案
2021/06/05 Python