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 相关文章推荐
jquery星级插件、支持页面中多次使用
Mar 25 Javascript
JavaScript 参数中的数组展开 [译]
Sep 21 Javascript
JavaScript、tab切换完整版(自动切换、鼠标移入停止、移开运行)
Jan 05 Javascript
基于JavaScript实现表单密码的隐藏和显示出来
Mar 02 Javascript
javascript事件冒泡简单示例
Jun 20 Javascript
Bootstrap Table从服务器加载数据进行显示的实现方法
Sep 29 Javascript
仿京东快报向上滚动的实例
Dec 13 Javascript
10行原生JS实现文字无缝滚动(超简单)
Jan 02 Javascript
JS严格模式知识点总结
Feb 27 Javascript
JS动画定时器知识总结
Mar 23 Javascript
Vue.js 图标选择组件实践详解
Dec 03 Javascript
手把手带你封装一个vue component第三方库
Feb 14 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 一个页面执行时间类代码
2010/03/05 PHP
PHP获取表单textarea数据中的换行问题
2010/09/10 PHP
php curl 登录163邮箱并抓取邮箱好友列表的代码(经测试)
2011/04/07 PHP
php中全局变量global的使用演示代码
2011/05/18 PHP
php代码收集表单内容并写入文件的代码
2012/01/29 PHP
基于empty函数的输出详解
2013/06/17 PHP
PHP实现通用alert函数的方法
2015/03/11 PHP
PHP入门教程之图像处理技巧分析
2016/09/11 PHP
thinkPHP5.0框架独立配置与动态配置方法
2017/03/17 PHP
laravel 框架结合关联查询 when()用法分析
2019/11/22 PHP
浅析jQuery1.8的几个小变化
2013/12/10 Javascript
JS日程管理插件FullCalendar中文说明文档
2017/02/06 Javascript
微信小程序左滑删除效果的实现代码
2017/02/20 Javascript
将angular-ui的分页组件封装成指令的方法详解
2017/05/10 Javascript
ReactNative实现图片上传功能的示例代码
2017/07/11 Javascript
vue组件Prop传递数据的实现示例
2017/08/17 Javascript
微信小程序wx.previewImage预览图片实例详解
2017/12/07 Javascript
React数据传递之组件内部通信的方法
2017/12/31 Javascript
vue实现动态表格提交参数动态生成控件的操作
2020/11/09 Javascript
Python数据结构与算法之链表定义与用法实例详解【单链表、循环链表】
2017/09/28 Python
Python批量查询关键词微信指数实例方法
2019/06/27 Python
CSS3弹性盒模型开发笔记(一)
2016/04/26 HTML / CSS
HTML5单选框、复选框、下拉菜单、文本域的实现代码
2020/12/01 HTML / CSS
Ryderwear澳洲官网:澳大利亚高端健身训练装备品牌
2018/09/18 全球购物
倩碧澳大利亚官网:Clinique澳大利亚
2019/07/22 全球购物
Douglas意大利官网:购买香水和化妆品
2020/05/27 全球购物
KTV的创业计划书范文
2014/02/02 职场文书
企业办公室岗位职责
2014/03/12 职场文书
公司任命书范本
2014/06/04 职场文书
运动会跳远广播稿5篇
2014/09/17 职场文书
大学生入党自荐书
2015/03/05 职场文书
2015年林业工作总结
2015/05/14 职场文书
国庆阅兵观后感
2015/06/15 职场文书
高三毕业感言
2015/07/30 职场文书
预防职务犯罪警示教育心得体会
2016/01/15 职场文书
python如何获取网络数据
2021/04/11 Python