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 相关文章推荐
URL地址中的#符号使用说明
Feb 12 Javascript
js onload事件不起作用示例分析
Oct 09 Javascript
JavaScritp添加url参数并将参数加入到url中及更改url参数的方法
Oct 26 Javascript
jQuery+Ajax实现无刷新操作
Jan 04 Javascript
fullpage.js全屏滚动插件使用实例
Sep 06 Javascript
js实现打地鼠小游戏
Feb 13 Javascript
js实现旋转木马效果
Mar 17 Javascript
移动端web滚动分页的实现方法
May 05 Javascript
JS获取一个表单字段中多条数据并转化为json格式
Oct 17 Javascript
vue中实现methods一个方法调用另外一个方法
Feb 08 Javascript
ES6中异步对象Promise用法详解
Jul 31 Javascript
Vue的编码技巧与规范使用详解
Aug 28 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
Terran热键控制
2020/03/14 星际争霸
php 进度条实现代码
2009/03/10 PHP
PHP禁止个别IP访问网站
2013/10/30 PHP
php获取服务器端mac和客户端mac的地址支持WIN/LINUX
2014/05/15 PHP
使用PHP和HTML5 FormData实现无刷新文件上传教程
2014/09/06 PHP
php删除文本文件中重复行的方法
2015/04/28 PHP
Javascript之旅 对象的原型链之由来
2010/08/25 Javascript
js网页滚动条滚动事件实例分析
2015/05/05 Javascript
JS简单实现多级Select联动菜单效果代码
2015/09/06 Javascript
JS+DIV+CSS实现的经典标签切换效果代码
2015/09/14 Javascript
详解nodejs 文本操作模块-fs模块(三)
2016/12/22 NodeJs
Bootstrap 手风琴菜单的实现代码
2017/01/20 Javascript
微信小程序搜索组件wxSearch实例详解
2017/06/08 Javascript
mongoose更新对象的两种方法示例比较
2017/12/19 Javascript
轻松搞定jQuery+JSONP跨域请求的解决方案
2018/03/06 jQuery
JS/jQuery实现超简单的Table表格添加,删除行功能示例
2019/07/31 jQuery
jQuery中DOM常见操作实例小结
2019/08/01 jQuery
微信小程序和H5页面间相互跳转代码实例
2019/09/19 Javascript
微信小程序 wx.getUserInfo引导用户授权问题实例分析
2020/03/09 Javascript
Python操作SQLite简明教程
2014/07/10 Python
浅谈Tensorflow由于版本问题出现的几种错误及解决方法
2018/06/13 Python
python中get和post有什么区别
2020/06/19 Python
python两个list[]相加的实现方法
2020/09/23 Python
CSS3实现瀑布流布局与无限加载图片相册的实例代码
2016/12/22 HTML / CSS
html5用video标签流式加载的实现
2020/05/20 HTML / CSS
卡骆驰新加坡官网:Crocs新加坡
2018/06/12 全球购物
JavaScript获取当前url根目录(路径)
2014/02/19 面试题
大学自主招生自荐信范文
2014/02/26 职场文书
小学雷锋月活动总结
2014/07/03 职场文书
向国旗敬礼活动小结
2014/09/27 职场文书
审计局班子四风对照检查材料思想汇报
2014/10/07 职场文书
公司财务经理岗位职责
2015/04/08 职场文书
财务统计员岗位职责
2015/04/14 职场文书
六五普法心得体会2016
2016/01/21 职场文书
CSS3 天气图标动画效果
2021/04/06 HTML / CSS
mysql中如何用命令创建联合唯一索引
2022/04/20 MySQL