67

I have a page where we're positioning a bunch of elements using CSS, and changing their "top and left" positions using JS.

I've had reports that these things have been misaligned, but a user has the motive to lie about this to "cheat", so I'm not exactly sure whether they're telling the truth. I'm trying to find a way to figure out whether they're lying or not, and to have some "proof".

I know that Canvas has a method to copy image information from an image element, or another canvas element (kind of a BitBlt operation).

Would it be possible to somehow, with Canvas (or with something else, Flash, whatever), take a "picture" of a piece of the page?
Again, I'm not trying to take information from an <image>. I'm trying to copy what the user sees, which is comprised of several HTML elements positioned absolutely (and I care most about those positions) and somehow upload that to the server.

I understand this can't be done, but maybe I'm missing something.

Any ideas?

hackjutsu
  • 6,728
  • 10
  • 39
  • 73
Daniel Magliola
  • 27,613
  • 56
  • 154
  • 235

7 Answers7

10

Somebody asked a question earlier that's somewhat similar to this. Scroll to the bottom of Youtube and click the "Report a Bug" link. Google's Feedback Tool (Javascript driven), essentially does what you described. Judging by what I looked at of its code, it uses canvas and has a JavaScript-based JPEG encoder which builds a JPG image to send off to Google.

It would definitely be a lot of work, but I'm sure you could accomplish something similar.

simshaun
  • 20,601
  • 1
  • 51
  • 69
  • Im sure that's flash bud, http://feedback.googleusercontent.com/117/FlashCanvas.swf – RobertPitt Dec 02 '10 at 21:51
  • 1
    It may be possible that they use Flash at some point, but I haven't seen it yet. All of the image creation is done with JavaScript and Canvas. I'd assume that Google would not put a Javascript JPEG encoder in their source unless they actually use it. Besides that, I've got Flashblock, so if it was Flash, it wouldn't work for me... – simshaun Dec 02 '10 at 21:54
  • Very interesting! Looks like I have some reverse-engineering to do. Thanks! – Daniel Magliola Dec 04 '10 at 11:51
  • 1
    I think canvas is just used for the highlight/blackout thing and not to take the screenshot. Check this out: http://stackoverflow.com/questions/4912092/using-html5-canvas-javascript-to-take-screenshots – Salman von Abbas May 25 '11 at 12:48
  • Google uses Flash for the _bare minimum_ on their main pages when they feel they must. From looking at the source, I think they even used Shockwave or something to do those interactive guitar strings on their search page that time. – Montagist Nov 22 '11 at 02:03
7

If a commercial solution is an option, Check out SnapEngage. Click on the "help" button in top-right to see it in action. Here is a screenshot:-

enter image description here

Setup is pretty straight-forward you just have to copy and paste a few lines of javascript code.

SnapEngage uses a Java Applet to take screenshots, Here is a blog post about how it works.

Camilo Martin
  • 34,128
  • 20
  • 104
  • 150
Salman von Abbas
  • 21,808
  • 8
  • 64
  • 56
  • VERY interesting, I need to see if they'd let me just call the "whatever it is" that takes the screenshot, rather than show the "report a bug" for, since this is supposed to happen in background, used shouldn't notice. But a great pointer. Thanks! – Daniel Magliola May 26 '11 at 12:53
  • Actually... reading through taht post, it looks like it asks the user for permission. The post says how they can ask for *less* permissions, but they still need to ask. Unfortunately this is not an option for me. But a good pointer nevertheless, thank you! – Daniel Magliola May 26 '11 at 12:55
  • [Usersnap](http://usersnap.com) is also a commercial solution for your question. You will get accurate screenshots from your visitors - even for Internet Explorer. And your users don't have to install anything (especially no Java or Flash!) – Gregor Jun 19 '13 at 15:35
  • @user824294 I blame StackOverflow. – Salman von Abbas Jun 19 '13 at 23:48
  • 1
    @Gregor Thanks, sounds good. Will check it out once the site is up again. – Salman von Abbas Jun 19 '13 at 23:55
  • Image was dead because StackOverflow automatically replaced `i.imgur` with `i.stack.imgur`. Fixed. – Camilo Martin Apr 07 '15 at 04:05
4

Yes you can See following demo In below code I have define table inside body tag but when you run this code then it will display image snapshot.

<!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 official Documentation:- http://html2canvas.hertzen.com/

To download html2canvas.js library you can use also if you unable to find from official link :- https://github.com/niklasvh/html2canvas/downloads [I am not responsible for this link :P :P :P]

Gourav Makhija
  • 480
  • 3
  • 16
  • 1
    Note that, while pretty good, what this does is different from a "screenshot", being more of "parse the DOM and build an image from that". For most cases this should be pretty good enough. – Camilo Martin Apr 07 '15 at 04:07
3

You can use the element, that currently is only supported by Firefox.

background: -moz-element(#mysite);

Here #mysite is the element whose content is used as background

Open in Firefox: http://jsfiddle.net/qu2kz/3/ (tested on FF 27)

snapshot

Community
  • 1
  • 1
Jose Rui Santos
  • 13,681
  • 7
  • 53
  • 69
  • 2
    Interesting. This doesn't quite solve the problem since it's Firefox only, but... Once you have that background in an element, how do you actually capture it in such a way that you can upload it to the server? – Daniel Magliola Feb 18 '14 at 19:13
  • Arrggh! I was almost there. My problem is how to copy that snapshot to a canvas context. Because once you have your snapshot in a canvas, then its easy to save or send the image back to server, by sending the base64 encoded string returned by the `canvas.toDataURL()` method. I will keep pushing and let you known if good news arise. – Jose Rui Santos Feb 18 '14 at 20:25
  • nowadays (two years after your reply) is there any chome feature same to -moz-element? – Lorenzo Sciuto Feb 26 '16 at 11:20
  • 1
    @LorenzoSciuto Unfortunately, this is still only supported by Mozilla, as you **[can see here.](https://developer.mozilla.org/en/docs/Web/CSS/element#Browser_compatibility)** – Jose Rui Santos Feb 26 '16 at 14:54
  • @JoseRuiSantos any clue about why chrome guys never implemented something similar? – Lorenzo Sciuto Feb 26 '16 at 15:33
  • 1
    @LorenzoSciuto Looks like the webkit team [did some work on this but was never released](https://bugs.webkit.org/show_bug.cgi?id=44650) – Jose Rui Santos Feb 26 '16 at 15:53
2

I don't think that you can do that. However, you could recursively fetch clientHeight, clientWidth, offsetTop and offsetLeft to determine the positions of all elements on the page and send it back to the server.

thejh
  • 41,293
  • 15
  • 89
  • 105
  • 1
    Yes, I thought of this, but one of the "hypotheses" is that I'm setting positions right, and somehow they're showing wrong. I don't quite buy this, but it *could* happen, that's why i'm looking for a graphical solution, to be really sure. – Daniel Magliola Dec 04 '10 at 11:47
  • The best way is to use percentages for all positions and size based on some parent element with position:relative. – trusktr Feb 20 '12 at 08:35
2

On Firefox, you can create an AddOn that uses canvas.drawWindow to draw web content to a canvas. https://developer.mozilla.org/en/Drawing_Graphics_with_Canvas#Rendering_Web_Content_Into_A_Canvas

I don't think there's a way to do that on WebKit at the moment.

Ilmari Heikkinen
  • 2,281
  • 17
  • 14
  • 1
    Thank you for your answer. Unfortunately, my plan was to use this as an "automatic error handler", if you will.... I can't ask the user to install an extension in my particular case. Thanks! – Daniel Magliola May 23 '11 at 15:58
  • This isn't an extension, it is a javascript method that renders webpage content to canvas. You can then use canvas2image to save it as an image. I thought I saw something about it working in Chrome... – trusktr Feb 20 '12 at 09:16
2

It can be done, with some limitations. There are some techniques, and these are exactly how many extensions do screenshots. From your description it seems that you aren't looking for a generic, client side solution to be deployed, but just something that a user or some users could use and submit, so I guess using an extension would be fine.

Chrome:

I can point you to my opensource Chrome extension, Blipshot, that does exactly that: https://github.com/folletto/Blipshot

Just to give some background:

  1. You can do that, as far as I know, only from inside an extension, since it uses an internal function.
  2. The function is chrome.tabs.captureVisibleTab and require access to the tabs from the manifest.
  3. The function grabs only the visible part of the active tab, so if you need just that it's fine. If you need something more, than, you should have a look at the whole script, since it's quite tricky to get the full page screenshot until Google fixes Bug #45209.

Firefox:

In Firefox since 1.5 you can build extensions that use a custom extension of canvas, drawWindow, that is more powerful than the chrome.tabs.captureVisibleTab equivalent of Chrome. Some informations are here: https://developer.mozilla.org/en/Drawing_Graphics_with_Canvas

Folletto
  • 1,725
  • 1
  • 10
  • 11
  • 1
    drawWindow doesn't work without FF? I thought I saw something about "Chrome privileges" in there... Is that Chrome browser or something specific to FF? – trusktr Feb 20 '12 at 09:19
  • Unfortunately, I was looking for something that works in a regular website, without the user installing, or even knowing what an extension is. It's also something that needs to happen without their explicit cooperation. – Daniel Magliola Feb 21 '12 at 12:03
  • 2
    @trusktr It's just an unfortunate naming choice by Google: "Chrome" is the part of the app UI (Firefox, Safari or else) that isn't the web page. A plugin that has "Chrome privileges" can access the Firefox UI entirely (since it's XML as well). – Folletto Feb 27 '12 at 21:30
  • @DanielMagliola Yes. That's what I meant: there's no way: "It can be done, with some limitations". I'm aware it's not the answer you are looking for, but as of today that's the correct one. :) – Folletto Feb 27 '12 at 21:33
  • @Folletto Aah, I see. Thanks. – trusktr Mar 04 '12 at 00:42