【问题标题】:canvas.toDataURL('image/svg+xml') returning "data:image/png;base64..."canvas.toDataURL('image/svg+xml') 返回 "data:image/png;base64..."
【发布时间】:2022-01-26 21:04:24
【问题描述】:

我正在尝试将画布导出到 svg 。但是 toDataURL 函数将数据返回为“data:image/png;base64...”

我不想使用复杂的函数/库。

如果有人可以修改它,我正在使用以下内容,这对我有帮助

             var dataURL=canvas.toDataURL('image/svg+xml');
             if (navigator.userAgent.indexOf("Safari") > -1 && 
             navigator.userAgent.indexOf("Chrome") === -1) {
                console.log(dataURL);
                window.open(dataURL);
              } else {
                 var parts = dataURL.split(';base64,');
                  var contentType = parts[0].split(":")[1];
                  var raw = window.atob(parts[1]);
                  var rawLength = raw.length;
                  var uInt8Array = new Uint8Array(rawLength);
                    console.log(uInt8Array);

                  for (var i = 0; i < rawLength; ++i) {
                    uInt8Array[i] = raw.charCodeAt(i);
                  }

                var blob = new Blob([uInt8Array], {type: "image/svg+xml;charset=utf-8"});
                var url = window.URL.createObjectURL(blob);

                var a = document.createElement("a");
                a.style = "display: none";
                a.href = url;
                a.download = orientation +".svg";

                document.body.appendChild(a);
                a.click();

                window.URL.revokeObjectURL(url);

【问题讨论】:

    标签: javascript canvas


    【解决方案1】:

    元素只保存一个像素缓冲区。
    尽管 2D API 主要基于矢量图,但实际内容只是光栅。

    导出到 svg 不是任何主流浏览器的选项。

    这意味着您的'image/svg+xml' 将不会在任何地方被识别,实际上它们会退回到image/png

    您说您不想使用复杂的函数/库,所以我们只是说您不走运,因为解决方案意味着覆盖所有绘图操作以构建可以映射到 SVG 元素的路径,这并不简单,(即使大部分都是可行的,除了 ImageData 像素操作)。
    如果你真的想这样做,那么你可能想看看一些库,this one 似乎只是为此目的而制作的,所以我希望它足够轻量级和足够的性能,尽管我从不 自己用过,fabricjs 也有这样的选择,不过那我们明显属于重量级。

    【讨论】:

    • 我使用了织物 js,其中 tosvg 函数不适用于我的情况。你也可以看到这个问题。 stackoverflow.com/questions/59242972/…
    • 你很好地问了这个问题,很多用户(其中​​包括 Durga)对 fabric.js 非常了解(比我自己多得多)所以请耐心等待,你会得到适当的答案.对于手头的问题,很抱歉答案具有欺骗性,但这是我唯一能做的。
    【解决方案2】:

    我的 vanilla js 解决方案可能会对您有所帮助,而无需使用 canvas.toDataURL 方式

    步骤

    1. 获取或创建一个 SVG 元素

    2. 使用XMLSerializer().serializeToStrin()序列化方法获取SVG字符串

    3. 使用window.btoa()方法将SVG字符串转换为base64字符串

    4. 手动创建data:image/svg+xml;类型base64 URL字符串

    5. 然后做你想做的事;比如下载图片等等。

    源代码

    const userName = "xgqfrms";
    
    const watermark = `
        <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg" viewBox="0 0 100 100" width="100" height="100">
            <text x="25" y="50" fill="#00ff00">${userName}</text>
        </svg>
    `;
    
    const app = document.querySelector(`#app`);
    app.insertAdjacentHTML('beforeend', watermark);
    
    const svgElement = document.querySelector(`#svg`);
    // console.log(`svgElement =`, svgElement);
    
    const svgURL = new XMLSerializer().serializeToString(svgElement);
    // console.log(`svgURL =`, svgURL);
    
    
    const imgSrc = `data:image/svg+xml;base64,${window.btoa(svgURL)}`;
    
    console.log(`imgSrc =`, imgSrc);
    
    const img = document.querySelector(`#img`);
    img.src = imgSrc;
      #app > svg {
          visibility: hidden;
          width: 0;
          height: 0;
      }
      #app {
          width: 100vw;
          height: 100vh;
          min-width: 1366px;
          min-height: 768px;
          overflow-x: hidden;
          overflow-y: auto;
      }
    <!DOCTYPE html>
    <html lang="zh-Hans">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <meta name="author" content="xgqfrms">
        <meta name="generator" content="VS code">
        <title>js canvas to base64 svg image</title>
    </head>
    <body>
        <main id="app">
            <img id="img" src=""/>
        </main>
    </body>
    </html>

    演示

    https://codepen.io/xgqfrms/pen/YzEzmxw

    【讨论】:

    • 问题是关于从 HTML 绘图到 SVG 图像。
    • 你是对的,但是使用canvas.toDataURL 不能做到这一点;所以我提供了另一种解决方案来获得预期的结果。
    • 好吧,我的意思是这不是想要的结果。
    猜你喜欢
    • 1970-01-01
    • 2012-12-20
    • 2015-12-23
    • 1970-01-01
    • 2012-10-01
    • 2015-07-29
    • 2016-03-20
    • 1970-01-01
    • 2016-03-14
    相关资源
    最近更新 更多