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 相关文章推荐
javascript原生和jquery库实现iframe自适应高度和宽度
Jul 18 Javascript
浅析jQuery Ajax请求参数和返回数据的处理
Feb 24 Javascript
AngularJS过滤器详解及示例代码
Aug 16 Javascript
AngularJS 工作原理详解
Aug 18 Javascript
如何实现星星评价(jquery.raty.js插件)
Dec 21 Javascript
JS文件/图片从电脑里面拖拽到浏览器上传文件/图片
Mar 08 Javascript
JavaScript异步加载问题总结
Feb 17 Javascript
Vue 开发音乐播放器之歌手页右侧快速入口功能
Aug 08 Javascript
微信小程序仿知乎实现评论留言功能
Nov 28 Javascript
layui表单验证select下拉框实现验证的方法
Sep 05 Javascript
Nuxt.js实现一个SSR的前端博客的示例代码
Sep 06 Javascript
解决VueCil代理本地proxytable无效报错404的问题
Nov 07 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安装ssh2扩展的方法【Linux平台】
2016/07/20 PHP
浅谈Coreseek、Sphinx-for-chinaese、Sphinx+Scws的区别
2016/12/15 PHP
yii插入数据库防并发的简单代码
2017/05/27 PHP
为jQuery.Treeview添加右键菜单的实现代码
2010/10/22 Javascript
javascript框架设计之框架分类及主要功能
2015/06/23 Javascript
JS基于myFocus库实现各种功能的tab选项卡切换效果
2015/09/19 Javascript
值得分享和收藏的Bootstrap学习教程
2016/05/12 Javascript
JQuery ZTree使用方法详解
2017/01/07 Javascript
jQuery+ThinkPHP+Ajax实现即时消息提醒功能实例代码
2017/03/21 jQuery
TypeScript入门-基本数据类型
2017/03/28 Javascript
JavaScript中的连续赋值问题实例分析
2019/07/12 Javascript
Vue中的循环及修改差值表达式的方法
2019/08/29 Javascript
JavaScript实现留言板案例
2020/03/17 Javascript
如何检测JavaScript中的死循环示例详解
2020/08/30 Javascript
vue3使用vue-count-to组件的实现
2020/12/25 Vue.js
JavaScript实现筛选数组
2021/03/02 Javascript
[53:44]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma BO3 第一场 1月31日
2021/03/11 DOTA
编写Python爬虫抓取豆瓣电影TOP100及用户头像的方法
2016/01/20 Python
Python3最长回文子串算法示例
2019/03/04 Python
学习和使用python的13个理由
2019/07/30 Python
详解Python Matplotlib解决绘图X轴值不按数组排序问题
2019/08/05 Python
使用OpenCV实现仿射变换—平移功能
2019/08/29 Python
python爬虫 Pyppeteer使用方法解析
2019/09/28 Python
python判断无向图环是否存在的示例
2019/11/22 Python
python 普通克里金(Kriging)法的实现
2019/12/19 Python
Python调用钉钉自定义机器人的实现
2020/01/03 Python
matplotlib.pyplot.matshow 矩阵可视化实例
2020/06/16 Python
python全栈开发语法总结
2020/11/22 Python
新春联欢会主持词
2014/03/24 职场文书
教育专业毕业生推荐信
2014/07/10 职场文书
无故旷工检讨书
2015/08/15 职场文书
幼儿体育课教学反思
2016/02/16 职场文书
详解Python牛顿插值法
2021/05/11 Python
Python制作一个随机抽奖小工具的实现
2021/07/07 Python
Mysql中where与on的区别及何时使用详析
2021/08/04 MySQL