将 SVG 作为图像复制到剪贴板

问题描述 投票:0回答:3

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

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

我还尝试了

document.execCommand('copy')
,通过使用图像创建一个div,但它仅在MS Word中对我有用,但在slack或堆栈溢出中不起作用(不知道为什么)。

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

有什么办法可以做到这一点吗?我对所有想法持开放态度。谢谢!

javascript image svg clipboard copy-paste
3个回答
0
投票

只是一些提示,不是真正的答案。我使用评论中的信息设置了一个本地示例:

<!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 策略,则可以避免这种污染。我仍然不确定该解决方案的可移植性。


0
投票

您只需复制“,”字符后面的 Base64 代码以结束 (

PHN2ZyB4bWxu...4=
) 并使用任何服务(如 base64.guru)将其转换为 SVG,然后将结果作为图像复制到剪贴板。

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

0
投票

为了扩展其他答案,这对我有用。


const image = new Image();
image.src = 'data:image/svg+xml,' + encodeURIComponent(svgElement.outerHTML);

await navigator.clipboard.write([new ClipboardItem({
    'image/png': new Promise((resolve) => {
        const canvas = document.createElement('canvas');
        canvas.width = image.naturalWidth;
        canvas.height = image.naturalHeight;
        const context = canvas.getContext('2d');
        context?.drawImage(image, 0, 0);

        canvas.toBlob((blob) => {
            if (blob) {
                resolve(blob);
            }
            canvas.remove();
        }, 'image/png');
    })
})]);

© www.soinside.com 2019 - 2024. All rights reserved.