简体   繁体   English

如何使用 JavaScript 截取 div 的屏幕截图?

[英]How to take screenshot of a div with JavaScript?

I am building something called the "HTML Quiz".我正在构建一个叫做“HTML Quiz”的东西。 It's completely ran on JavaScript and it's pretty cool.它完全在 JavaScript 上运行,非常酷。

At the end, a results box pops up that says "Your Results:" and it shows how much time they took, what percentage they got, and how many questions they got right out of 10. I would like to have a button that says "Capture results" and have it somehow take a screenshot or something of the div, and then just show the image captured on the page where they can right click and "Save image as."最后,会弹出一个结果框,上面写着“你的结果:”,它显示了他们花了多少时间,他们得到了多少百分比,以及他们从 10 个问题中得到了多少个问题。我想要一个按钮,上面写着“捕获结果”并让它以某种方式截取 div 的屏幕截图或其他内容,然后只在页面上显示捕获的图像,他们可以在页面上右键单击并“将图像另存为”。

I really would love to do this so they can share their results with others.我真的很想这样做,这样他们就可以与他人分享他们的成果。 I don't want them to "copy" the results because they can easily change that.我不希望他们“复制”结果,因为他们可以很容易地改变它。 If they change what it says in the image, oh well.如果他们改变图片中的内容,哦,好吧。

Does anyone know a way to do this or something similar?有谁知道这样做或类似的方法吗?

No, I don't know of a way to 'screenshot' an element, but what you could do, is draw the quiz results into a canvas element, then use the HTMLCanvasElement object's toDataURL function to get a data: URI with the image's contents.不,我不知道有什么方法可以对元素进行“屏幕截图”,但您可以做的是将测验结果绘制到画布元素中,然后使用HTMLCanvasElement对象的toDataURL函数获取data:带有图像内容的 URI .

When the quiz is finished, do this:测验完成后,请执行以下操作:

var c = document.getElementById('the_canvas_element_id');
var t = c.getContext('2d');
/* then use the canvas 2D drawing functions to add text, etc. for the result */

When the user clicks "Capture", do this:当用户单击“捕获”时,执行以下操作:

window.open('', document.getElementById('the_canvas_element_id').toDataURL());

This will open a new tab or window with the 'screenshot', allowing the user to save it.这将打开一个带有“屏幕截图”的新选项卡或窗口,允许用户保存它。 There is no way to invoke a 'save as' dialog of sorts, so this is the best you can do in my opinion.没有办法调用各种“另存为”对话框,所以在我看来这是你能做的最好的事情。

This is an expansion of @Dathan's answer , using html2canvas and FileSaver.js .这是@Dathan's answer的扩展,使用html2canvasFileSaver.js

$(function() { 
    $("#btnSave").click(function() { 
        html2canvas($("#widget"), {
            onrendered: function(canvas) {
                theCanvas = canvas;


                canvas.toBlob(function(blob) {
                    saveAs(blob, "Dashboard.png"); 
                });
            }
        });
    });
});

This code block waits for the button with the id btnSave to be clicked.此代码块等待单击 id 为btnSave按钮。 When it is, it converts the widget div to a canvas element and then uses the saveAs() FileSaver interface (via FileSaver.js in browsers that don't support it natively) to save the div as an image named "Dashboard.png".当它是时,它将widget div 转换为画布元素,然后使用 saveAs() FileSaver 接口(通过本地不支持它的浏览器中的 FileSaver.js)将 div 保存为名为“Dashboard.png”的图像.

An example of this working is available at this fiddle .这个工作的一个例子可以在这个小提琴上找到

After hours of research, I finally found a solution to take a screenshot of an element, even if the origin-clean FLAG is set (to prevent XSS), that´s why you can even capture for example Google Maps (in my case).经过数小时的研究,我终于找到了一个解决方案来截取元素的截图,即使设置了origin-clean FLAG(以防止 XSS),这就是为什么你甚至可以捕获例如谷歌地图(在我的情况下) . I wrote a universal function to get a screenshot.我写了一个通用函数来获取屏幕截图。 The only thing you need in addition is the html2canvas library ( https://html2canvas.hertzen.com/ ).此外,您唯一需要的是 html2canvas 库 ( https://html2canvas.hertzen.com/ )。

Example:例子:

getScreenshotOfElement($("div#toBeCaptured").get(0), 0, 0, 100, 100, function(data) {
    // in the data variable there is the base64 image
    // exmaple for displaying the image in an <img>
    $("img#captured").attr("src", "data:image/png;base64,"+data);
});

Keep in mind console.log() and alert() won´t generate output if the size of the image is great.请记住,如果图像的大小很大,则console.log()alert()不会生成输出。

Function:功能:

function getScreenshotOfElement(element, posX, posY, width, height, callback) {
    html2canvas(element, {
        onrendered: function (canvas) {
            var context = canvas.getContext('2d');
            var imageData = context.getImageData(posX, posY, width, height).data;
            var outputCanvas = document.createElement('canvas');
            var outputContext = outputCanvas.getContext('2d');
            outputCanvas.width = width;
            outputCanvas.height = height;

            var idata = outputContext.createImageData(width, height);
            idata.data.set(imageData);
            outputContext.putImageData(idata, 0, 0);
            callback(outputCanvas.toDataURL().replace("data:image/png;base64,", ""));
        },
        width: width,
        height: height,
        useCORS: true,
        taintTest: false,
        allowTaint: false
    });
}

If you wish to have "Save as" dialog, just pass image into php script, which adds appropriate headers如果您希望有“另存为”对话框,只需将图像传递到 php 脚本中,它会添加适当的标题

Example "all-in-one" script script.php示例“多合一”脚本script.php

<?php if(isset($_GET['image'])):
    $image = $_GET['image'];

    if(preg_match('#^data:image/(.*);base64,(.*)$#s', $image, $match)){
        $base64 = $match[2];
        $imageBody = base64_decode($base64);
        $imageFormat = $match[1];

        header('Content-type: application/octet-stream');
        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private", false); // required for certain browsers
        header("Content-Disposition: attachment; filename=\"file.".$imageFormat."\";" ); //png is default for toDataURL
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: ".strlen($imageBody));
        echo $imageBody;
    }
    exit();
endif;?>

<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver=1.7.2'></script>
<canvas id="canvas" width="300" height="150"></canvas>
<button id="btn">Save</button>
<script>
    $(document).ready(function(){
        var canvas = document.getElementById('canvas');
        var oCtx = canvas.getContext("2d");
        oCtx.beginPath();
        oCtx.moveTo(0,0);
        oCtx.lineTo(300,150);
        oCtx.stroke();

        $('#btn').on('click', function(){
            // opens dialog but location doesnt change due to SaveAs Dialog
            document.location.href = '/script.php?image=' + canvas.toDataURL();
        });
    });
</script>
var shot1=imagify($('#widget')[0], (base64) => {
  $('img.screenshot').attr('src', base64);
});

Take a look at htmlshot package , then, check deeply the client side section:看看htmlshot package ,然后,深入检查客户端部分:

npm install htmlshot

Add this Script in your index.html在 index.html 中添加此脚本

<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>

Use this function to get screenshot of div tag使用此函数获取 div 标签的截图

  getScreenShot(){
    let c = this.elem.nativeElement.querySelector('.chartContainer'); // or document.getElementById('canvas');
    html2canvas(c).then((canvas:any)=>{
      var t = canvas.toDataURL().replace("data:image/png;base64,", "");
      this.downloadBase64File('image/png',t,'image');
    })
  }

downloadBase64File(contentType:any, base64Data:any, fileName:any) {
  const linkSource = `data:${contentType};base64,${base64Data}`;
  const downloadLink = document.createElement("a");
  downloadLink.href = linkSource;
  downloadLink.download = fileName;
  downloadLink.click();
}

You can't take a screen-shot: it would be an irresponsible security risk to let you do so.你不能截屏:让你这样做会带来不负责任的安全风险。 However, you can:但是,您可以:

  • Do things server-side and generate an image在服务器端做事并生成图像
  • Draw something similar to a Canvas and render that to an image (in a browser that supports it)绘制类似于 Canvas 的东西并将其渲染为图像(在支持它的浏览器中)
  • Use some other drawing library to draw directly to the image (slow, but would work on any browser)使用其他一些绘图库直接绘制到图像上(很慢,但可以在任何浏览器上使用)

Another alternative is to use GrabzIt's JavaScript API all you need to do is pass the CSS selector of the div you want to capture. 另一个替代方法是使用GrabzIt的JavaScript API ,只需传递要捕获的div的CSS选择器即可。 It will then create a screenshot of just that div. 然后它将创建该div的屏幕截图。

<script type="text/javascript" src="grabzit.min.js"></script>
<script type="text/javascript">
GrabzIt("YOUR APPLICATION KEY").ConvertURL("http://www.example.com/quiz.html",
{"target": "#results", "bheight": -1, "height": -1, "width": -1}).Create();
</script>

There is more examples here solving how to capture HTML elements . 这里有更多示例解决了如何捕获HTML元素 For full disclosure I am the API creator. 为了全面披露我是API创建者。

It's to simple you can use this code for capture the screenshot of particular area you have to define the div id in html2canvas.很简单,您可以使用此代码捕获特定区域的屏幕截图,您必须在 html2canvas 中定义 div id。 I'm using here 2 div-:我在这里使用 2 div-:

div id="car" div id="汽车"
div id ="chartContainer" div id ="chartContainer"
if you want to capture only cars then use car i'm capture here car only you can change chartContainer for capture the graph html2canvas($('#car') copy and paste this code如果您只想捕获汽车,那么使用汽车,我只捕获汽车,您可以更改chartContainer以捕获图形html2canvas($('#car')复制并粘贴此代码

 <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script> <script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous"> <script> window.onload = function () { var chart = new CanvasJS.Chart("chartContainer", { animationEnabled: true, theme: "light2", title:{ text: "Simple Line Chart" }, axisY:{ includeZero: false }, data: [{ type: "line", dataPoints: [ { y: 450 }, { y: 414}, { y: 520, indexLabel: "highest",markerColor: "red", markerType: "triangle" }, { y: 460 }, { y: 450 }, { y: 500 }, { y: 480 }, { y: 480 }, { y: 410 , indexLabel: "lowest",markerColor: "DarkSlateGrey", markerType: "cross" }, { y: 500 }, { y: 480 }, { y: 510 } ] }] }); chart.render(); } </script> </head> <body bgcolor="black"> <div id="wholebody"> <a href="javascript:genScreenshotgraph()"><button style="background:aqua; cursor:pointer">Get Screenshot of Cars onl </button> </a> <div id="car" align="center"> <i class="fa fa-car" style="font-size:70px;color:red;"></i> <i class="fa fa-car" style="font-size:60px;color:red;"></i> <i class="fa fa-car" style="font-size:50px;color:red;"></i> <i class="fa fa-car" style="font-size:20px;color:red;"></i> <i class="fa fa-car" style="font-size:50px;color:red;"></i> <i class="fa fa-car" style="font-size:60px;color:red;"></i> <i class="fa fa-car" style="font-size:70px;color:red;"></i> </div> <br> <div id="chartContainer" style="height: 370px; width: 100%;"></div> <script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script> <div id="box1"> </div> </div>> </body> <script> function genScreenshotgraph() { html2canvas($('#car'), { onrendered: function(canvas) { var imgData = canvas.toDataURL("image/jpeg"); var pdf = new jsPDF(); pdf.addImage(imgData, 'JPEG', 0, 0, -180, -180); pdf.save("download.pdf"); } }); } </script> </html>

<script src="/assets/backend/js/html2canvas.min.js"></script>


<script>
    $("#download").on('click', function(){
        html2canvas($("#printform"), {
            onrendered: function (canvas) {
                var url = canvas.toDataURL();

                var triggerDownload = $("<a>").attr("href", url).attr("download", getNowFormatDate()+"电子签名详细信息.jpeg").appendTo("body");
                triggerDownload[0].click();
                triggerDownload.remove();
            }
        });
    })
</script>

quotation引述

As far as I know you can't do that, I may be wrong.据我所知你不能这样做,我可能是错的。 However I'd do this with php, generate a JPEG using php standard functions and then display the image, should not be a very hard job, however depends on how flashy the contents of the DIV are但是我会用 php 来做这个,使用 php 标准函数生成一个 JPEG,然后显示图像,应该不是一件很困难的工作,但是取决于 DIV 的内容有多华丽

Add to your html file and id="capture" to the div you want to take screenshot添加到您的 html 文件并将 id="capture" 添加到您要截取屏幕截图的 div

<a id="btn-Convert-Html2Image" href="#">Download</a>
<script src="capture.js"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js" type="text/javascript"></script> 

in capture.js add在 capture.js 添加

document.getElementById("btn-Convert-Html2Image").addEventListener("click", function() {
    html2canvas(document.getElementById("capture")).then(function (canvas) {            var anchorTag = document.createElement("a");
            anchorTag.download = "filename.jpg";
            anchorTag.href = canvas.toDataURL();
            anchorTag.target = '_blank';
            anchorTag.click();
        });
});

then just press donwload and it will download the screenshot然后只需按 donwload 它就会下载截图

Or you can view screenshot img by add或者您可以通过添加查看截图 img

<div id="previewImg"></div>

in html code is where you want to view that img and js code will be在 html 代码中,您要查看 img 和 js 代码的位置

document.getElementById("btn-Convert-Html2Image").addEventListener("click", function() {
    html2canvas(document.getElementById("capture")).then(function (canvas) {            
            var anchorTag = document.createElement("a");
            document.body.appendChild(anchorTag);
            document.getElementById("previewImg").appendChild(canvas);
            anchorTag.click();
        });
});

As far as I know its not possible with javascript.据我所知,javascript 是不可能的。

What you can do for every result create a screenshot, save it somewhere and point the user when clicked on save result.您可以为每个结果做些什么创建一个屏幕截图,将其保存在某处并在单击保存结果时指向用户。 (I guess no of result is only 10 so not a big deal to create 10 jpeg image of results) (我想没有结果只有 10 个所以创建 10 个 jpeg 结果图像没什么大不了的)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM