【问题标题】:Copy SVG to clipboard as image将 SVG 作为图像复制到剪贴板
【发布时间】:2021-01-14 17:50:03
【问题描述】:

我正在开发一个应用程序,我想为 svg 提供一个复制按钮,以便将其作为图像复制到剪贴板,可以粘贴到其他地方。

我尝试使用剪贴板 API,但它有很多安全限制,而且它似乎不适用于 http 并且仅适用于 png。

我还尝试了document.execCommand('copy'),方法是使用图像创建一个 div,但它仅适用于 MS Word,但不适用于松弛或堆栈溢出(不知道为什么)。

我想通过 Javascript 复制 chrome/firefox 的右键单击上下文菜单的 Copy Image 选项的行为。

有没有办法做到这一点?我对所有想法持开放态度。谢谢!

【问题讨论】:

  • 如果有一些代码可以修改就好了。根据您的需要,您可以尝试使用 javascript 在 canvas 中绘制 svg,如下例所示:tutorialspoint.com/How-to-draw-an-SVG-file-on-an-HTML5-canvas
  • 我探索了一个用于编写画布的选项,但是如何将其作为图像复制到剪贴板?
  • 对不起,我被关于右键的句子弄糊涂了。对于您的问题,我认为剪贴板 API 没有任何办法。 execCommand策略导出的不是图片,而是html代码。这就是为什么它适用于 Word,但不适用于图像处理器。您可以在 developer.mozilla.org/en-US/docs/Web/API/Clipboard/write 找到有用的示例,但有一些警告。怕是头疼,不便携。
  • 谢谢@vqf。知道 chrome/firefox 是如何做到的吗?我怀疑他们可能使用的不是 JS 中提供的 API。任何见解或链接都会很棒。
  • 您希望它复制/粘贴什么样的图像? SVG 图像?那么你拥有的标记就是 svg 图像。光栅图像?如果在哪个维度上光栅化,为什么?在哪个州? (请记住,svg 图像可以通过 SMIL 或 CSS 进行动画处理,甚至可以交互)

标签: javascript image svg clipboard copy-paste


【解决方案1】:

您可以简单地将 Base64 代码复制到 ',' 字符以结束 (PHN2ZyB4bWxu...4=) 并使用任何服务(如 base64.guru)将其转换为 SVG,然后将结果复制到您的剪贴板作为图像。

data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIiB3aWR0aD0iNDQ4IiBoZWlnaHQ9IjUxMiI+PHBhdGggZmlsbD0iIzNhNWI4NyIgZD0iTTAgNDY0YzAgMjYuNSAyMS41IDQ4IDQ4IDQ4aDM1MmMyNi41IDAgNDgtMjEuNSA0OC00OFYxOTJIMHYyNzJ6bTMyMC0xOTZjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJoLTQwYy02LjYgMC0xMi01LjQtMTItMTJ2LTQwem0wIDEyOGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMmgtNDBjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTE5MiAyNjhjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJoLTQwYy02LjYgMC0xMi01LjQtMTItMTJ2LTQwem0wIDEyOGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMmgtNDBjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTY0IDI2OGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMkg3NmMtNi42IDAtMTItNS40LTEyLTEydi00MHptMCAxMjhjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJINzZjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTQwMCA2NGgtNDhWMTZjMC04LjgtNy4yLTE2LTE2LTE2aC0zMmMtOC44IDAtMTYgNy4yLTE2IDE2djQ4SDE2MFYxNmMwLTguOC03LjItMTYtMTYtMTZoLTMyYy04LjggMC0xNiA3LjItMTYgMTZ2NDhINDhDMjEuNSA2NCAwIDg1LjUgMCAxMTJ2NDhoNDQ4di00OGMwLTI2LjUtMjEuNS00OC00OC00OHoiPjwvcGF0aD48L3N2Zz4=

【讨论】:

    【解决方案2】:

    只是一些提示,而不是实际答案。我使用 cmets 中的信息设置了一个本地示例:

    <!DOCTYPE html>
    <html>
    <body>
    <canvas id="myCanvas" style="border:2px solid green;" width="300" height="300"> 
    </canvas>
          <script>
            function copyCanvas() {
              let canvas = document.getElementById('myCanvas');
              canvas.toBlob(function (blob) {
                let data = [new ClipboardItem({ [blob.type]: blob })];
    
                navigator.clipboard.write(data).then(function () {
                  alert('Copied');
                }, function (err) {
                  alert('Not copied');
                })
              });
            }
      
             let canvas = document.getElementById('myCanvas');
             let ctx = canvas.getContext('2d');
             var data = `<svg xmlns="http://www.w3.org/2000/svg" width="300"
             height="200">' +
                '<foreignObject width="100%" height="100%">' +
                   '<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:50px">' +
                      'Simply Easy ' +
                      '<span style="color:blue;">' +
                      'Learning</span>' +
                   '</div>' +
                '</foreignObject>' +
             '</svg>`;
             var DOMURL = window.URL || window.webkitURL || window;
             var img1 = new Image();
             var svg = new Blob([data], {type: 'image/svg+xml'});
             var url = DOMURL.createObjectURL(svg);
             img1.onload = function() {
                ctx.drawImage(img1, 25, 70);
                DOMURL.revokeObjectURL(url);
             }
             img1.src = url;
             setTimeout(copyCanvas, 3000);
          </script>
    </body>
    </html>
    

    这不起作用,但它可能是一个开始。如果直接调用copyCanvas(),而没有setTimeout,我会在Chrome 中得到一张大小合适的黑色图片。我认为这意味着画布仍未绘制。随着延迟,画布显示图片,但我收到一条错误消息,说它不能用toBlob 转换,因为它被污染了。这是解释here。如果您可以在服务器中设置 CORS 策略,您可能会避免这种污染。我仍然不确定解决方案的可移植性。

    【讨论】:

      猜你喜欢
      • 2012-08-28
      • 2023-03-11
      • 2011-09-04
      • 1970-01-01
      • 2011-04-19
      • 2021-07-27
      • 2013-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多