您可以使用 Canvas 对页面进行“截图”吗?

Posted

技术标签:

【中文标题】您可以使用 Canvas 对页面进行“截图”吗?【英文标题】:Can you take a "screenshot" of the page using Canvas? 【发布时间】:2011-05-19 09:51:33 【问题描述】:

我有一个页面,我们使用 CSS 定位一堆元素,并使用 JS 更改它们的“顶部和左侧”位置。

我收到报告称这些事情有误,但用户有动机对此撒谎以“作弊”,所以我不确定他们是否说的是真话。我正试图找到一种方法来判断他们是否在撒谎,并找到一些“证据”。

我知道 Canvas 有一种方法可以从图像元素或另一个画布元素(一种 BitBlt 操作)复制图像信息。

是否有可能使用 Canvas(或其他东西,Flash 等)以某种方式为页面的一部分拍摄“照片”? 同样,我不想从<image> 获取信息。我正在尝试复制用户看到的内容,它由几个绝对定位的 html 元素组成(我最关心这些位置)并以某种方式将其上传到服务器。

我知道这无法完成,但也许我遗漏了一些东西。

有什么想法吗?

【问题讨论】:

【参考方案1】:

之前有人问过一个与此有些相似的问题。滚动到 Youtube 底部,然后单击“报告错误”链接。谷歌的反馈工具(javascript 驱动),基本上就是你所描述的。从我查看的代码来看,它使用画布并具有基于 JavaScript 的 JPEG 编码器,该编码器构建 JPG 图像以发送给 Google。

这肯定是很多工作,但我相信你可以完成类似的事情。

【讨论】:

我确定那是闪存,feedback.googleusercontent.com/117/FlashCanvas.swf 他们可能会在某个时候使用 Flash,但我还没有看到。所有的图像创建都是使用 JavaScript 和 Canvas 完成的。我假设谷歌不会在他们的源代码中加入 Javascript JPEG 编码器,除非他们实际使用它。除此之外,我还有 Flashblock,所以如果是 Flash,它对我不起作用...... 非常有趣!看起来我有一些逆向工程要做。谢谢! 我认为画布只是用于高亮/遮光而不是截屏。看看这个:***.com/questions/4912092/… Google 在认为必须时在其主页上使用 Flash 来最低限度。从源码看,我想他们当时甚至在他们的搜索页面上使用了 Shockwave 或其他东西来做那些交互式吉他弦。【参考方案2】:

如果可以选择商业解决方案,请查看SnapEngage。 单击右上角的“帮助”按钮以查看它的运行情况。这是截图:-

设置非常简单,您只需复制并粘贴几行 javascript 代码即可。

SnapEngage 使用 Java Applet 截取屏幕截图,Here 是一篇关于其工作原理的博文。

【讨论】:

非常有趣,我需要看看他们是否会让我只调用截取屏幕截图的“无论是什么”,而不是显示“报告错误”,因为这应该发生在后台,使用不应该注意到。但是一个很好的指针。谢谢! 其实...阅读 taht 帖子,它看起来像是在请求用户许可。该帖子说明了他们如何请求 less 权限,但他们仍然需要询问。不幸的是,这不是我的选择。不过还是不错的指点,谢谢! Usersnap 也是您问题的商业解决方案。您将从访问者那里获得准确的屏幕截图 - 即使是 Internet Explorer。而且您的用户无需安装任何东西(尤其是没有 Java 或 Flash!) @user824294 我怪 ***。 @Gregor 谢谢,听起来不错。网站重新启动后会检查一下。【参考方案3】:

是的,您可以查看以下演示 在下面的代码中,我在 body 标记内定义了表格,但是当您运行此代码时,它将显示图像快照。

<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>test2</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.js"></script> 
<script type="text/javascript" src="js/html2canvas.js?rev032"></script> 
<script type="text/javascript">
  $(document).ready(function() 
  var target = $('body');
   html2canvas(target, 
     onrendered: function(canvas) 
     var data = canvas.toDataURL();
     alert(data);
     document.body.innerHTML="<br/><br/><br/><br/><br/><br/><img src="+data+" />";
   
 );
);
</script>       

 </head>
 <body>  
 <h1>Testing</h1>
 <h4>One column:</h4>
 <table border="1">
 <tr>
  <td>100</td>
 </tr>
 </table>
</body>

html2canvas 官方文档:- http://html2canvas.hertzen.com/

要下载 html2canvas.js 库,如果您无法从官方链接中找到,您也可以使用:- https://github.com/niklasvh/html2canvas/downloads [我不对这个链接负责 :P :P :P]

【讨论】:

请注意,虽然非常好,但它的作用与“屏幕截图”不同,更多的是“解析 DOM 并从中构建图像”。在大多数情况下,这应该已经足够好了。【参考方案4】:

您可以使用element,目前只有 Firefox 支持。

background: -moz-element(#mysite);

这里#mysite是其内容作为背景的元素

在 Firefox 中打开:http://jsfiddle.net/qu2kz/3/ (在 FF 27 上测试)

【讨论】:

有趣。这并不能完全解决问题,因为它只是 Firefox,但是......一旦你在一个元素中有了这个背景,你如何实际捕获它,以便你可以将它上传到服务器? 啊!我快到了。我的问题是如何将该快照复制到画布上下文中。因为一旦您在画布中获得快照,就可以通过发送canvas.toDataURL() 方法返回的base64 编码字符串轻松保存或将图像发送回服务器。如果有好消息,我会继续推动并通知您。 现在(在您回复两年后)是否有任何与 -moz-element 相同的 chome 功能? @LorenzoSciuto 不幸的是,这仍然只有 Mozilla 支持,因为你 can see here. @LorenzoSciuto 看起来像 webkit 团队did some work on this but was never released【参考方案5】:

我认为你做不到。但是,您可以递归地获取clientHeightclientWidthoffsetTopoffsetLeft 以确定页面上所有元素的位置并将其发送回服务器。

【讨论】:

是的,我想到了这一点,但“假设”之一是我设置的位置正确,但不知何故,它们显示错误。我不太买这个,但它可能发生,这就是为什么我正在寻找图形解决方案,真的。 最好的方法是使用百分比来表示所有位置和大小,基于某些父元素的位置:相对。【参考方案6】:

在 Firefox 上,您可以创建一个使用 canvas.drawWindow 将 Web 内容绘制到画布的插件。 https://developer.mozilla.org/en/Drawing_Graphics_with_Canvas#Rendering_Web_Content_Into_A_Canvas

我认为目前在 WebKit 上没有办法做到这一点。

【讨论】:

感谢您的回答。不幸的是,我的计划是使用它作为“自动错误处理程序”,如果你愿意的话……我不能要求用户在我的特殊情况下安装扩展程序。谢谢! 这不是扩展,它是一种将网页内容呈现到画布的javascript方法。然后,您可以使用 canvas2image 将其保存为图像。我以为我在 Chrome 中看到了一些关于它的工作......【参考方案7】:

可以做到,但有一些限制。有一些技巧,而这些正是多少个扩展做截图。根据您的描述,您似乎不是在寻找要部署的通用客户端解决方案,而只是用户或某些用户可以使用和提交的东西,所以我想使用扩展程序就可以了。

铬:

我可以为您指出我的开源 Chrome 扩展程序 Blipshot,它正是这样做的: https://github.com/folletto/Blipshot

只是提供一些背景:

    据我所知,您只能从扩展内部执行此操作,因为它使用内部函数。 函数是chrome.tabs.captureVisibleTab,需要访问清单中的选项卡。 该函数只抓取活动选项卡的可见部分,所以如果您只需要它就可以了。如果您需要更多内容,则应该查看整个脚本,因为在 Google 修复 Bug #45209 之前获取整页屏幕截图非常棘手。

火狐:

在 Firefox 1.5 之后,您可以构建使用自定义画布扩展 drawWindow 的扩展,这比 chrome.tabs.captureVisibleTab 等效的 Chrome 更强大。一些信息在这里: https://developer.mozilla.org/en/Drawing_Graphics_with_Canvas

【讨论】:

drawWindow 没有 FF 就不能工作?我以为我在那里看到了一些关于“Chrome 特权”的东西……是那个 Chrome 浏览器还是 FF 特有的东西? 不幸的是,我一直在寻找可以在常规网站上运行的东西,而无需用户安装,甚至不知道扩展是什么。这也是需要在没有他们明确合作的情况下发生的事情。 @trusktr 这只是谷歌的一个不幸的命名选择:“Chrome”是应用程序 UI(Firefox、Safari 或其他)的一部分,而不是网页。具有“Chrome 权限”的插件可以完全访问 Firefox UI(因为它也是 XML)。 @DanielMagliola 是的。这就是我的意思:没有办法:“可以做到,但有一些限制”。我知道这不是您要寻找的答案,但截至今天,这是正确的答案。 :) @Folletto 啊,我明白了。谢谢。

以上是关于您可以使用 Canvas 对页面进行“截图”吗?的主要内容,如果未能解决你的问题,请参考以下文章

javascript 网页截图 保存为本地图片

JS 使用 html2canvas 实现页面截图功能

WPF -- 使用RenderTargetBitmap将Canvas保存为图片

html2canvas截图的清晰度问题

canvas2html 遇到的跨域问题

html2canvas截图不全或空白