解决使用svg绘制后下载图片以及下载svg内部嵌套image图片失败的问题。

news2025/8/14 4:25:41

在使用svg进行图形绘制之后,可能需要下载已经绘制的svg图片,我们可能会遇到以下两种情况:
情况1:

    <svg width="640" height="400" xmlns="http://www.w3.org/2000/svg" id="svgColumn">
        <text x="200" y="20" font-size="20">SVG 华东地区手机12个月的数据 柱状图</text>
        <line x1="20" y1="380" x2="620" y2="380" stroke="black" stroke-width="1.5" />
        <line x1="20" y1="380" x2="20" y2="1" style="stroke: black; stroke-width: 1.5" />
        <path d="M600 360 L620 380 L600 400 Z" style="stroke: black; stroke-width: 1" />
        <path d="M1 20 L20 1 L40 20 Z" style="stroke: black; stroke-width: 1" />
    </svg>

情况2:

    <svg width="640" height="400" xmlns="http://www.w3.org/2000/svg" id="svgColumn">
        <text x="200" y="20" font-size="20">SVG 华东地区手机12个月的数据 柱状图</text>
        <line x1="20" y1="380" x2="620" y2="380" stroke="black" stroke-width="1.5" />
        <line x1="20" y1="380" x2="20" y2="1" style="stroke: black; stroke-width: 1.5" />
        <path d="M600 360 L620 380 L600 400 Z" style="stroke: black; stroke-width: 1" />
        <path d="M1 20 L20 1 L40 20 Z" style="stroke: black; stroke-width: 1" />
        <image id="demoImg" width="250" href="./2ad33d6ed244630e8526343c390156e5.jpeg">
        </image>
    </svg>

第一种是svg内部都是使用svg的方法进行绘制的,我们可以直接通过canvas的方法进行绘制下载,方法如下

    let downEle = document.getElementById(`download`);

    downEle.addEventListener("click", function () {
        downloadpng();
    })

    function downloadpng() {
        let rootNode = document.getElementById(`svgColumn`);
        var serializer = new XMLSerializer();
        var source =
            '<?xml version="1.0" standalone="no"?>\r\n' +
            serializer.serializeToString(rootNode);

        var image = new Image();
        image.src =
            "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source);

        image.onload = () => {
            var canvas = document.createElement("canvas");
            canvas.width = 640;
            canvas.height = 500;
            var context = canvas.getContext("2d");
            context.fillStyle = "#fff"; //设置背景
            context.fillRect(0, 0, 640, 500);
            context.drawImage(image, 0, 0, 640, 500, 0, 0, 640, 500);   //进行绘制图片
            var url = canvas.toDataURL("image/jpeg"); // 这就是得到的base64编码
            var pngName = `${this.phaseId}`;
            var a = document.createElement("a");
            a.download = '测试名字' + ".jpeg";
            a.href = url;
            a.click();
        };
    }

第二种情况是在svg内部嵌套了一个image的图片,此时则无法使用第一种方法直接进行下载,下载的图片无内嵌图片,后来通过调查发下,需要把image引入的图片的路径更改微base64的方法后,再进行下载则可以实现,并解决问题。方法如下。

   let newImgUrl = ''

    //图片转化base64
    const toBase64 = (img) => {
        var canvas = document.createElement("canvas");
        canvas.width = 250; 
        canvas.height = 250;
        var context = canvas.getContext("2d");
        context.fillStyle = "#fff"; // 设置保存后的PNG 是白色的
        context.fillRect(0, 0, 250, 250);
        context.drawImage(img, 0, 0, 250, 250);  //进行绘制图片
        var url = canvas.toDataURL("image/jpeg"); // 这就是得到的base64编码
        newImgUrl = url;
        console.log(newImgUrl,'newImgUrlnewImgUrl')
        var demoImg = document.getElementById("demoImg");         

        demoImg.setAttribute("href",newImgUrl)
    }


    //传入路径转化成图片
    const getImageUrlBase64 = (url) => {
        const img = new Image();
        img.crossOrigin = 'anonymous';//处理跨域,后端也要设置跨域处理才行
        img.src = url;
        img.onload = () => {
            toBase64(img);
        }
    }


    getImageUrlBase64("./2ad33d6ed244630e8526343c390156e5.jpeg")  //传入需要更改的路径

通过此种方法就可以解决svg内部嵌套image图片下载异常的问题了。

完成的html例子如下,本地调试的话,可以把html文件单独放在文件夹内,内嵌一张自己的图片,打开vscode 使用 Open with live server插件即可进行调试使用。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <svg width="640" height="400" xmlns="http://www.w3.org/2000/svg" id="svgColumn">
        <text x="200" y="20" font-size="20">SVG 华东地区手机12个月的数据 柱状图</text>
        <line x1="20" y1="380" x2="620" y2="380" stroke="black" stroke-width="1.5" />
        <line x1="20" y1="380" x2="20" y2="1" style="stroke: black; stroke-width: 1.5" />
        <path d="M600 360 L620 380 L600 400 Z" style="stroke: black; stroke-width: 1" />
        <path d="M1 20 L20 1 L40 20 Z" style="stroke: black; stroke-width: 1" />
        <image id="demoImg" width="250" href="./2ad33d6ed244630e8526343c390156e5.jpeg">
        </image>
    </svg>

    <button id="download">下载按钮</button>
</body>

<script>
    let downEle = document.getElementById(`download`);

    downEle.addEventListener("click", function () {
        downloadpng();
    })

    function downloadpng() {
        let rootNode = document.getElementById(`svgColumn`);
        var serializer = new XMLSerializer();
        var source =
            '<?xml version="1.0" standalone="no"?>\r\n' +
            serializer.serializeToString(rootNode);

        var image = new Image();
        image.src =
            "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source);

        image.onload = () => {
            var canvas = document.createElement("canvas");
            canvas.width = 640;
            canvas.height = 500;
            var context = canvas.getContext("2d");
            context.fillStyle = "#fff"; //设置背景
            context.fillRect(0, 0, 640, 500);
            context.drawImage(image, 0, 0, 640, 500, 0, 0, 640, 500);   //进行绘制图片
            var url = canvas.toDataURL("image/jpeg"); // 这就是得到的base64编码
            var pngName = `${this.phaseId}`;
            var a = document.createElement("a");
            a.download = '测试名字' + ".jpeg";
            a.href = url;
            a.click();
        };
    }

    let newImgUrl = ''

    //图片转化base64
    const toBase64 = (img) => {
        var canvas = document.createElement("canvas");
        canvas.width = 250; 
        canvas.height = 250;
        var context = canvas.getContext("2d");
        context.fillStyle = "#fff"; // 设置保存后的PNG 是白色的
        context.fillRect(0, 0, 250, 250);
        context.drawImage(img, 0, 0, 250, 250);  //进行绘制图片
        var url = canvas.toDataURL("image/jpeg"); // 这就是得到的base64编码
        newImgUrl = url;
        console.log(newImgUrl,'newImgUrlnewImgUrl')
        var demoImg = document.getElementById("demoImg");         

        demoImg.setAttribute("href",newImgUrl)
    }
    //传入路径转化成图片
    const getImageUrlBase64 = (url) => {
        const img = new Image();
        img.crossOrigin = 'anonymous';//处理跨域,后端也要设置跨域处理才行
        img.src = url;
        img.onload = () => {
            toBase64(img);
        }
    }
    getImageUrlBase64("./2ad33d6ed244630e8526343c390156e5.jpeg")  //传入需要更改的路径
</script>

</html>

文件夹截图:
在这里插入图片描述
效果图:
在这里插入图片描述

下载的效果图:
在这里插入图片描述

如有问题请评论沟通

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/14938.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决问题 - 错误:不支持发行版本 5

文章目录一、提出问题二、解决问题&#xff08;一&#xff09;设置项目SDK与语言等级&#xff08;二&#xff09;设置模块语言等级&#xff08;三&#xff09;设置Java编译器等级&#xff08;四&#xff09;运行程序&#xff0c;测试问题是否已解决一、提出问题 基于JDK11创建…

阿里Redis最全面试全攻略,读完这个就可以和阿里面试官好好聊聊

简述Redis常用的数据结构及其如何实现的&#xff1f; Redis支持的常用5种数据类型指的是value类型&#xff0c;分别为&#xff1a;字符串String、列表List、哈希Hash、集合Set、有序集合Zset&#xff0c;但是Redis后续又丰富了几种数据类型分别是Bitmaps、HyperLogLogs、GEO。…

年搜索量超 7 亿次背后:这款 APP 用火山引擎 DataTester 完成“数据驱动”

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 双十一刚过&#xff0c;双十二在即&#xff0c;随着线上营销玩法的层出不穷&#xff0c;各平台之间的价格逐渐“内卷”。消费者对跨平台比价的需求越来越强烈&#…

【实时语音转文本】PC端实时语音转文本(麦克风外音系统内部音源)

语音转文字这个功能可以应用在视频动态字幕&#xff0c;语音快速输入&#xff0c;实时记录通话内容&#xff0c;高级应用可以在人工智能&#xff0c;语音识别&#xff0c;智能助手方面&#xff0c;还需要一点机器学习可以做出一些好玩的东西&#xff0c;比如PC端AI助理&#xf…

给开源项目做一个漂亮简洁的版本迭代更新图,生成固定链接复制到介绍中、公众号菜单链接中、博客中和网页中等

背景 开源项目的版本迭代与更新经常需要更新迭代文档&#xff0c;但是readme.md没有比较美观一点的效果&#xff0c;所以文本分享一种第三方的方式&#xff1a;用TexSpire的免费在线文档分享功能&#xff0c;手机、PC、Pad都可以适配。 效果预览 使用 视频教程 第一步&…

重磅 | 思特威获得ISO 26262:2018汽车功能安全ASIL D流程认证证书

确保安全是汽车制造商和系统供应商的责任。为了从芯片IP级开始解决功能安全问题&#xff0c;国际标准化组织&#xff08;ISO&#xff09;在2018年追加了汽车半导体的功能安全评估指南。 彼时&#xff0c;新车搭载的芯片数量、种类以及软件代码行数开始呈现倍数增长。按照ISO 2…

重磅!华秋电子再次入选“中国产业数字化百强榜”

11月16日&#xff0c;由江苏省商务厅、南京市人民政府指导&#xff0c;南京市商务局主办的江苏电子商务大会暨第九届中国产业数字化年会在南京开幕。 据了解&#xff0c;会议上公开发布了“2022中国产业数字化百强榜”&#xff0c;这也是托比网自2015年以来发布的第13个榜单。榜…

ES6解构赋值及ES6的一些简写介绍

1、ES6解构赋值&#xff1a; ● 解构赋值&#xff0c;就是快速地从对象或者数组中取出成员的一个语法方式 (1) 解构数组&#xff1a; ● 快速从数组中获取成员 <script>//ES5的方式从数组中获取成员var arr [Jack,Rose,Tom]var a arr[0] //Jackvar b arr[1] //Ro…

实验六 数组(山东建筑大学)

第1关:实验6.1 任务描述 输入3个整数,按由大到小的顺序输出。 输入样例 1 1 2 3 输出样例 1 3 2 1 开始你的任务吧,祝你成功! 第2关:实验6.2 任务描述 输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。 输入样例 1 2 1 3 4 5 6 7 8 10 9 输…

感性认识一下Linux的进程地址空间和写时拷贝技术

虽然本篇文章对操作系统的理解不怎么深入&#xff0c;或者说仅仅是一些皮毛知识(也可能皮毛也算不上)&#xff0c;但还是需要读者有一些Linux的基础理解&#xff0c;如何确定是否有这些基础呢&#xff1f;可以参考我的这一篇博客&#xff1a;Linux —— 进程概念超详解! 1.“奇…

LeetCode 318 周赛

2460. 对数组执行操作 给你一个下标从 0 开始的数组 nums &#xff0c;数组大小为 n &#xff0c;且由 非负 整数组成。 你需要对数组执行 n - 1 步操作&#xff0c;其中第 i 步操作&#xff08;从 0 开始计数&#xff09;要求对 nums 中第 i 个元素执行下述指令&#xff1a;…

阿里 P8 架构师力荐 java 程序员人手一套 116 页 JVM 吊打面试官专属秘籍

只要是 java 程序员&#xff0c;肯定对于 JVM 来说并不陌生&#xff0c;甚至是从熟悉到陌生&#xff0c;为什么这样说呢&#xff1f;因为你看似熟悉的东西&#xff0c;其实对于源码层级了解得少之又少&#xff0c;到头来只有一种陌生的感觉&#xff0c;使用了吗&#xff1f;使用…

技术分享 | 多测试环境的动态伸缩实践

本文将从敏捷研发团队的环境需求与痛点出发&#xff0c;分享如何基于云构建可弹性伸缩的自动化生成式多测试环境&#xff1b;更在经济效益层面&#xff0c;提供了多种成本优化方案&#xff0c;以满足研发团队低成本、高效益的多测试环境运行目标。 一、当前遇到的环境问题 初…

论文阅读笔记 | 三维目标检测——AVOD算法

如有错误&#xff0c;恳请指出。 文章目录1. 背景2. 网络结构3. 实验结果paper&#xff1a;《Joint 3D Proposal Generation and Object Detection from View Aggregation》 1. 背景 AVOD同样是一个two-stage(使用了RPN提取候选框)、anchor-based网络结构。获得较高的召回率对…

【WPF】DiffPlex 文本比对工具

【WPF】DiffPlex 文本比对工具背景关于 DiffPlex准备代码实现效果图源码下载地址背景 现行的文本编辑器大多都具备文本查询的能力&#xff0c;但是并不能直观的告诉用户两段文字的细微差异&#xff0c;所以对比工具在某种情况下&#xff0c;就起到了很便捷的效率。 关于 DiffPl…

D. Extreme Subtraction(差分)

Problem - 1443D - Codeforces 给你一个由n个正整数组成的数组a。 你可以随意使用下面的操作&#xff1a;选择任何一个1≤k≤n的整数&#xff0c;做两件事中的一件。 将数组中的前k个元素递减1。 将数组的最后k个元素递减1。 例如&#xff0c;如果n5&#xff0c;a[3,2,2,1,4]…

【Pytorch with fastai】第 16 章 :训练过程

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

利用jemalloc优化mysql

此方法管理mysql内存也存在一定的弊端&#xff0c;根据自身情况进行选择 优点&#xff1a; jemalloc的确能对内存做一定优化&#xff0c;但是发现并不能解决所有内存碎片问题&#xff0c;只能说有一定缓解作用。 缺点&#xff1a; 使用jemalloc会带来内存增加问题&#xff0…

[附源码]java毕业设计零食销售系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

MySQL8.0 MySQL事务日志、REDO日志、UNDO日志

文章目录学习资料MySQL事务日志REDO日志REDO日志的好处、特点好处特点REDO的组成REDO的整体流程REDO LOG的刷盘策略流程图UNDO日志如何理解UNDO日志UNDO日志的作用作用1&#xff1a;回滚数据作用2&#xff1a;MVCC小结学习资料 【MySQL数据库教程天花板&#xff0c;mysql安装到…