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 相关文章推荐
根据分辩率调用不同的CSS.
Jan 08 Javascript
JS中字符问题(二进制/十进制/十六进制及ASCII码之间的转换)
Nov 03 Javascript
javascript 获取页面的高度及滚动条的位置的代码
May 06 Javascript
JS对HTML标签select的获取、添加、删除操作
Oct 17 Javascript
js动态创建上传表单通过iframe模拟Ajax实现无刷新
Feb 20 Javascript
使用jspdf生成pdf报表
Jul 03 Javascript
jQuery实现鼠标经过事件的延时处理效果
Aug 20 Javascript
基于javascript实现漂亮的页面过渡动画效果附源码下载
Oct 26 Javascript
jQuery实现页面下拉100像素出现悬浮窗口的方法
Sep 05 Javascript
JS实现简单的二元方程计算器功能示例
Jan 03 Javascript
Angular ui.bootstrap.pagination分页
Jan 20 Javascript
layui表格分页 记录勾选的实例
Sep 02 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
phpMyAdmin下载、安装和使用入门教程
2007/05/31 PHP
php数组函数序列之next() - 移动数组内部指针到下一个元素的位置,并返回该元素值
2011/10/31 PHP
Yii使用Captcha验证码的方法
2015/12/28 PHP
php pthreads多线程的安装与使用
2016/01/19 PHP
Yii2-GridView 中让关联字段带搜索和排序功能示例
2017/01/21 PHP
JS的replace方法详细介绍
2012/11/09 Javascript
原生javascript实现分享到朋友圈功能 支持ios和android
2016/05/11 Javascript
ionic js 模型 $ionicModal 可以遮住用户主界面的内容框
2016/06/06 Javascript
Javascript实现图片不间断滚动的代码
2016/06/22 Javascript
jQuery插件FusionWidgets实现的AngularGauge图效果示例【附demo源码】
2017/03/23 jQuery
js a标签点击事件
2017/03/30 Javascript
JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法
2017/04/28 Javascript
详解vue-cli脚手架build目录中的dev-server.js配置文件
2017/11/24 Javascript
vue中子组件向父组件传递数据的实例代码(实现加减功能)
2018/04/20 Javascript
python使用arp欺骗伪造网关的方法
2015/04/24 Python
Django中的“惰性翻译”方法的相关使用
2015/07/27 Python
python开发环境PyScripter中文乱码问题解决方案
2016/09/11 Python
Python  pip安装lxml出错的问题解决办法
2017/02/10 Python
Python中logging实例讲解
2019/01/17 Python
如何通过雪花算法用Python实现一个简单的发号器
2019/07/03 Python
利用python实现短信和电话提醒功能的例子
2019/08/08 Python
详解Python list和numpy array的存储和读取方法
2019/11/06 Python
在python里创建一个任务(Task)实例
2020/04/25 Python
日本最佳原创设计品牌:Felissimo(芬理希梦)
2019/03/19 全球购物
美体小铺波兰官方网站:The Body Shop波兰
2019/09/03 全球购物
文明餐桌活动方案
2014/02/11 职场文书
运动会方阵口号
2014/06/07 职场文书
家长会欢迎标语
2014/06/24 职场文书
飞机制造技术专业求职信
2014/07/27 职场文书
教师党员学习十八届四中全会思想汇报
2014/11/03 职场文书
小学优秀学生评语
2014/12/29 职场文书
公司保洁员岗位职责
2015/02/13 职场文书
初中班主任培训心得体会
2016/01/07 职场文书
浅谈MySQL表空间回收的正确姿势
2021/10/05 MySQL
Apache Pulsar结合Hudi构建Lakehouse方案分析
2022/03/31 Servers
Java 获取Word中所有的插入和删除修订的方法
2022/04/06 Java/Android