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 相关文章推荐
判断是否输入完毕再激活提交按钮
Jun 26 Javascript
当前页禁止复制粘贴截屏代码小集
Jul 24 Javascript
验证手机号码的JS方法分享
Sep 10 Javascript
JQ获取动态加载的图片大小的正确方法分享
Nov 08 Javascript
node.js cookie-parser之parser.js
Jun 06 Javascript
第八篇Bootstrap下拉菜单实例代码
Jun 21 Javascript
解决wx.onMenuShareTimeline出现的问题
Aug 16 Javascript
完美实现js焦点轮播效果(二)(图片可滚动)
Mar 07 Javascript
vue-resource 拦截器(interceptor)的使用详解
Jul 04 Javascript
浅谈vue后台管理系统权限控制思考与实践
Dec 19 Javascript
JS实现的新闻列表自动滚动效果示例
Jan 30 Javascript
vue按需加载实例详解
Sep 06 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中文本数据翻页(留言本翻页)
2006/10/09 PHP
PHP实现PDO的mysql数据库操作类
2014/12/12 PHP
PHP PDO操作MySQL基础教程
2017/06/05 PHP
Javascript入门学习资料收集整理篇
2008/07/06 Javascript
选择TreeView控件的树状数据节点的JS方法(jquery)
2010/02/06 Javascript
基于jquery的网页SELECT下拉框美化代码
2010/10/28 Javascript
鼠标右击事件代码(asp.net后台)
2011/01/27 Javascript
javascript闭包的理解
2015/04/01 Javascript
如何让一个json文件显示在表格里【实现代码】
2016/05/09 Javascript
深入浅出ES6新特性之函数默认参数和箭头函数
2016/08/01 Javascript
jQuery EasyUI右键菜单实现关闭标签/选项卡
2016/10/10 Javascript
JS中substring与substr的用法
2016/11/16 Javascript
深入理解Vue生命周期、手动挂载及挂载子组件
2017/09/27 Javascript
vue 之 .sync 修饰符示例详解
2018/04/21 Javascript
Vue中的Props(不可变状态)
2018/09/29 Javascript
关于layui表单中按钮自动提交的解决方法
2019/09/09 Javascript
python将MongoDB里的ObjectId转换为时间戳的方法
2015/03/13 Python
python实现web方式logview的方法
2015/08/10 Python
讲解Python的Scrapy爬虫框架使用代理进行采集的方法
2016/02/18 Python
一个基于flask的web应用诞生 记录用户账户登录状态(6)
2017/04/11 Python
修复 Django migration 时遇到的问题解决
2018/06/14 Python
Linux下Python安装完成后使用pip命令的详细教程
2018/11/22 Python
浅谈python 导入模块和解决文件句柄找不到问题
2018/12/15 Python
python实现远程控制电脑
2019/05/23 Python
利用selenium爬虫抓取数据的基础教程
2019/06/10 Python
python实现PID算法及测试的例子
2019/08/08 Python
Django框架中间件定义与使用方法案例分析
2019/11/28 Python
使用Python求解带约束的最优化问题详解
2020/02/11 Python
使用Python实现将多表分批次从数据库导出到Excel
2020/05/15 Python
Python如何读写字节数据
2020/08/05 Python
python 实现aes256加密
2020/11/27 Python
RentCars.com巴西:汽车租赁网站
2016/08/22 全球购物
美国儿童玩具、装扮和玩偶商店:Magic Cabin
2018/09/02 全球购物
物流仓储实习自我鉴定
2013/09/25 职场文书
淘宝店策划方案
2014/06/07 职场文书
Win11怎么跳过联网验机 ?Win11跳过联网验机激活教程
2022/04/05 数码科技