【问题标题】:Copy Canvas-generated Img (Images) to MS-Word将 Canvas 生成的 Img(图像)复制到 MS-Word
【发布时间】:2020-04-01 10:39:26
【问题描述】:

试图将多个图像(从 img 标记项)复制到 MS-Word...

(我已将帖子修改为使用工作画布并仅渲染 img 项目。)

以前曾提出过类似的问题(例如,Copy/paste html inline image from browser to word processors)。关于复制画布的那些似乎都解决了(目前)“它不能完成”。关于从 img 项目复制的那些似乎解决了使用上下文菜单(将图像另存为...)。但是,我找到了一个可能的实例,我想知道发生了什么。

(再次注意,我说的只是复制和粘贴 img 项目,而不是画布。)

如果我渲染一个 WWWeb 页面(在示例中,Firefox 为 https://www.amazon.com/gcx/Electronics-Gift-Guide/gfhz/events/ref=12DOD19_GW_Desk_DashQuad_Giftingv1_EN_EGG?categoryId=egg19-hol-main&pf_rd_p=510b75ea-83a1-4950-8c98-6febeef7ac00&pf_rd_r=SBWFNQ6X1WTRGEBCJ03G):

并选择并复制多个图像:

然后我可以粘贴到 MS-Word(相当旧的 MS-Word 2010):

它不漂亮,但它确实有效(这里,我使用了 MS-Word 的合并格式)。

如果我渲染以下代码:

<head>
    <title>Try Canvas-generated Img</title>
    <script>
        function PageOnLoad() { //handle load event on page
            // Create a work canvas, draw a simple image in it, and then copy that image to the img items.
            var /*canvas (result)*/ cvs = document.createElement('canvas');
            cvs.height = document.getElementById('testIMG1').clientHeight;
            cvs.width = document.getElementById('testIMG1').clientWidth;
            var /*context*/ ctx = cvs.getContext('2d');
            ctx.fillStyle = 'silver';
            ctx.fillRect(0, 0, cvs.width, cvs.height);
            ctx.fillStyle = 'black';
            ctx.moveTo(0, 0);
            ctx.lineTo(cvs.width, cvs.height);
            ctx.stroke();

            // Copy canvas image to both img items.
            document.getElementById('testIMG1').src = cvs.toDataURL('image/jpg'); //Amazon page's images are JPEGs
            document.getElementById('testIMG2').src = cvs.toDataURL('image/jpg');
        }
    </script>
</head>
<body onload="PageOnLoad();">
    <table width="50%">
        <tr>
            <td align="right">Img 1:</td>
            <td><img id="testIMG1" style="border:solid;height:30px;width:100px;" /></td>
        </tr>
        <tr>
            <td align="right">Img 2:</td>
            <td><img id="testIMG2" style="border:solid;height:30px;width:100px;" /></td>
        </tr>
    </table>
</body>
</html>

JSFiddle:https://jsfiddle.net/kL58ox0m/6/

并选择(在本例中,Ctrl-A 表示全选)并复制:

粘贴到 MS-Word 时,我得到了 bupkus/zilch/nada/zippo:

为什么会失败(或者相反,为什么它在亚马逊页面上有效 - 是的,我确实给他们发了电子邮件......还没有答案)?谢谢!

更新: 我尝试了 alexyorke 指出的方法,但没有任何乐趣。这是修改后的代码:

  <title>Try Canvas-generated Img</title>
  <script>
    function CopyOnClick() {
      var /*source*/ src = document.getElementById('sourceDIV');
      if (document.body.createTextRange) {
        var /*range*/ rng = document.body.createTextRange();
        rng.moveToElementText(src);
        rng.select();
      } else if (window.getSelection) {
        var /*range*/ rng = document.createRange();
        rng.selectNodeContents(src);
        var /*selection*/ slc = window.getSelection();
        slc.removeAllRanges();
        slc.addRange(rng);
      }
      document.execCommand('Copy');
      document.body.removeChild(itm);
    }

    function PageOnLoad() { //handle load event on page
      // Create a work canvas, draw a simple image in it, and then copy that image to the img items.
      var /*canvas (result)*/ cvs = document.createElement('canvas');
      cvs.height = document.getElementById('testIMG1').clientHeight;
      cvs.width = document.getElementById('testIMG1').clientWidth;
      var /*context*/ ctx = cvs.getContext('2d');
      ctx.fillStyle = 'silver';
      ctx.fillRect(0, 0, cvs.width, cvs.height);
      ctx.fillStyle = 'black';
      ctx.moveTo(0, 0);
      ctx.lineTo(cvs.width, cvs.height);
      ctx.stroke();

      // Copy canvas image to both img items.
      document.getElementById('testIMG1').src = cvs.toDataURL('image/jpg'); //Amazon page's images are JPEGs
      document.getElementById('testIMG2').src = cvs.toDataURL('image/jpg');
    }

  </script>
</head>

<body onload="PageOnLoad();">
  <div id="sourceDIV" contenteditable>
    <table width="50%">
      <tr>
        <td align="right">Img 1:</td>
        <td><img id="testIMG1" style="border:solid;height:30px;width:100px;" /></td>
      </tr>
      <tr>
        <td align="right">Img 2:</td>
        <td><img id="testIMG2" style="border:solid;height:30px;width:100px;" /></td>
      </tr>
    </table>
    <input onclick="CopyOnClick();" style="border:solid;" type="button" value="Copy All" />
  </div>
</body>

JSFiddle 位于 https://jsfiddle.net/7jks53ht/23/

感谢 Rainb 的链接(肯定比自己写东西要好)。这是我的 JSFiddle 代码生成的:

<!--StartFragment-->
    <table width="50%">
      <tbody><tr>
        <td align="right">Img 1:</td>
        <td><img id="testIMG1" style="border:solid;height:30px;width:100px;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAABFklEQVRoge2Xy6kEIRQFe2sMGoMxmIMxGIM5GIMxaAqd2XmrgYv0Y5hPj7fbsygQVwcKCu4WQoAxBt57pJRQa8W+72QS2+NRSkGMEc45OOcQY0QpZfrA1diOPmutSCnBew9jDEIIyDmjtTZ98N05FCLpvSPnDKZNiZCRR9qstUybBiESpk2ZEAnTpkzICNOmTIiEaVMmRMK0KRMywoNUmRAJ06ZMiGTVtKkVMrJK2i4jRPJf2nrv07ctKURyt7RdXsjI1dN2OyGSK6bt1kIkrbVLpG0ZISNa07asEImmtFHIwOy0UcgTZNqstaenjUJe4Bdpo5A3OSttFPIlvpU2CjmBT9JGISfzatoo5Mc8O0gpZCJHafsD9O0j0HvOOn4AAAAASUVORK5CYII="></td>
      </tr>
      <tr>
        <td align="right">Img 2:</td>
        <td><img id="testIMG2" style="border:solid;height:30px;width:100px;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAABFklEQVRoge2Xy6kEIRQFe2sMGoMxmIMxGIM5GIMxaAqd2XmrgYv0Y5hPj7fbsygQVwcKCu4WQoAxBt57pJRQa8W+72QS2+NRSkGMEc45OOcQY0QpZfrA1diOPmutSCnBew9jDEIIyDmjtTZ98N05FCLpvSPnDKZNiZCRR9qstUybBiESpk2ZEAnTpkzICNOmTIiEaVMmRMK0KRMywoNUmRAJ06ZMiGTVtKkVMrJK2i4jRPJf2nrv07ctKURyt7RdXsjI1dN2OyGSK6bt1kIkrbVLpG0ZISNa07asEImmtFHIwOy0UcgTZNqstaenjUJe4Bdpo5A3OSttFPIlvpU2CjmBT9JGISfzatoo5Mc8O0gpZCJHafsD9O0j0HvOOn4AAAAASUVORK5CYII="></td>
      </tr>
    </tbody></table>

  <!--EndFragment-->
</body>
</html>

我在那里看到了图像,但是,正如我所说,我在复制到 MS-Word 时并不高兴。

更新 2: 最后一次尝试...我删除了表结构,因为我看到复制的片段包含引用。

现在,代码是:

  <title>Try Canvas-generated Img</title>
  <script>
    function CopyOnClick() {
      var /*source*/ src = document.getElementById('sourceDIV');
      if (document.body.createTextRange) {
        var /*range*/ rng = document.body.createTextRange();
        rng.moveToElementText(src);
        rng.select();
      } else if (window.getSelection) {
        var /*range*/ rng = document.createRange();
        rng.selectNodeContents(src);
        var /*selection*/ slc = window.getSelection();
        slc.removeAllRanges();
        slc.addRange(rng);
      }
      document.execCommand('Copy');
      document.body.removeChild(itm);
    }

    function PageOnLoad() { //handle load event on page
      // Create a work canvas, draw a simple image in it, and then copy that image to the img items.
      var /*canvas (result)*/ cvs = document.createElement('canvas');
      cvs.height = document.getElementById('testIMG1').clientHeight;
      cvs.width = document.getElementById('testIMG1').clientWidth;
      var /*context*/ ctx = cvs.getContext('2d');
      ctx.fillStyle = 'silver';
      ctx.fillRect(0, 0, cvs.width, cvs.height);
      ctx.fillStyle = 'black';
      ctx.moveTo(0, 0);
      ctx.lineTo(cvs.width, cvs.height);
      ctx.stroke();

      // Copy canvas image to both img items.
      document.getElementById('testIMG1').src = cvs.toDataURL('image/jpg'); //Amazon page's images are JPEGs
      document.getElementById('testIMG2').src = cvs.toDataURL('image/jpg');
    }

  </script>
</head>

<body onload="PageOnLoad();">
  <div id="sourceDIV" contenteditable>
    Img 1:<img id="testIMG1" style="border:solid;height:30px;width:100px;" />
    <br />Img 2:<img id="testIMG2" style="border:solid;height:30px;width:100px;" />
    <br /><input onclick="CopyOnClick();" style="border:solid;" type="button" value="Copy All" />
  </div>
</body>

(JSFiddle at [https://jsfiddle.net/7jks53ht/31/)

它会产生:

<html><body>
<!--StartFragment-->
    Img 1:<img id="testIMG1" style="border:solid;height:30px;width:100px;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAABFklEQVRoge2Xy6kEIRQFe2sMGoMxmIMxGIM5GIMxaAqd2XmrgYv0Y5hPj7fbsygQVwcKCu4WQoAxBt57pJRQa8W+72QS2+NRSkGMEc45OOcQY0QpZfrA1diOPmutSCnBew9jDEIIyDmjtTZ98N05FCLpvSPnDKZNiZCRR9qstUybBiESpk2ZEAnTpkzICNOmTIiEaVMmRMK0KRMywoNUmRAJ06ZMiGTVtKkVMrJK2i4jRPJf2nrv07ctKURyt7RdXsjI1dN2OyGSK6bt1kIkrbVLpG0ZISNa07asEImmtFHIwOy0UcgTZNqstaenjUJe4Bdpo5A3OSttFPIlvpU2CjmBT9JGISfzatoo5Mc8O0gpZCJHafsD9O0j0HvOOn4AAAAASUVORK5CYII=">
    <br>Img 2:<img id="testIMG2" style="border:solid;height:30px;width:100px;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAABFklEQVRoge2Xy6kEIRQFe2sMGoMxmIMxGIM5GIMxaAqd2XmrgYv0Y5hPj7fbsygQVwcKCu4WQoAxBt57pJRQa8W+72QS2+NRSkGMEc45OOcQY0QpZfrA1diOPmutSCnBew9jDEIIyDmjtTZ98N05FCLpvSPnDKZNiZCRR9qstUybBiESpk2ZEAnTpkzICNOmTIiEaVMmRMK0KRMywoNUmRAJ06ZMiGTVtKkVMrJK2i4jRPJf2nrv07ctKURyt7RdXsjI1dN2OyGSK6bt1kIkrbVLpG0ZISNa07asEImmtFHIwOy0UcgTZNqstaenjUJe4Bdpo5A3OSttFPIlvpU2CjmBT9JGISfzatoo5Mc8O0gpZCJHafsD9O0j0HvOOn4AAAAASUVORK5CYII=">
    <br>
  <!--EndFragment-->
</body>
</html>

...不过,没有喜悦(叹息)。

【问题讨论】:

标签: javascript html canvas ms-word copy-paste


【解决方案1】:

如果您想将它们复制到 word 中,您需要自己将画布转换为图像。屏幕截图浮现在脑海。可能还有其他方法。探索使用 SVG - 我没有来源,但我相信它们在浏览器之外得到更好的支持。


TL;DR;

复制/粘贴是一个 3 部分过程。

  1. 源应用程序告诉操作系统它在剪贴板上有数据,以及它支持什么格式。
  2. 操作系统会跟踪您从哪个应用程序复制数据。
  3. 当您粘贴到目标应用程序中时,目标应用程序会告诉操作系统它支持什么格式。
  4. 操作系统请求源应用程序目标应用程序格式化数据并在进程之间移动字节。

-- 请看这里 (How is copy paste possible?)

那么你哪里出了问题?

在第一个示例中,浏览器(源应用程序)能够将文本和图像翻译成 Word 可以理解的格式(目标应用程序)。

在第二个示例中,浏览器无法将画布转换为图像,或者 Word 接受的格式。这并不奇怪,因为它不是浏览器软件工程师的最佳使用方式来完成这项工作。

纯文本/unicode 是数据的后备,因为几乎所有东西都可以处理 unicode,而且在大多数情况下已经足够了。

【讨论】:

    【解决方案2】:

    我认为 Microsoft Word 不会从网络浏览器复制任何图像,除非图像存储在本地。

    如果您从互联网上的任何地方加载带有图像的页面并尝试将其复制到 word 中,它不会这样做。

    但是,如果您保存网页的完整副本以便它在本地存储图像,在浏览器中打开保存的网页,然后再次复制,它会起作用。

    这甚至也适用于存储在内存中的图像(例如,以 blob 形式)。它也不会复制那些。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-09
      • 2014-10-01
      相关资源
      最近更新 更多