web-dev-qa-db-fra.com

Comment faire une capture d'écran d'une div avec JavaScript?

Je construis quelque chose qui s'appelle le "Quiz HTML". Il est complètement exécuté sur JavaScript et c'est plutôt cool.

À la fin, une boîte de résultats apparaît avec le message "Vos résultats:" et indique le temps qu’ils ont pris, le pourcentage de réponses obtenues et le nombre de questions qu’ils ont eues sur 10. Je souhaite un bouton indiquant: "Capturez les résultats" et faites-le en quelque sorte prendre une capture d'écran ou quelque chose de la div, puis affichez simplement l'image capturée sur la page, où ils pourront cliquer avec le bouton droit de la souris et "Enregistrer l'image sous".

J'aimerais vraiment faire cela afin qu'ils puissent partager leurs résultats avec d'autres. Je ne veux pas qu'ils "copient" les résultats, car ils peuvent facilement changer cela. S'ils changent le contenu de l'image, eh bien.

Est-ce que quelqu'un connaît un moyen de faire ceci ou quelque chose de similaire? 

141
Nathan

Non, je ne connais pas de moyen de "capturer" un élément, mais vous pouvez aussi dessiner les résultats du questionnaire dans un élément de canevas, puis utiliser la fonction HTMLCanvasElement de l'objet toDataURL pour obtenir un URI data: avec le contenu de l'image.

Lorsque le test est terminé, procédez comme suit:

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 */

Lorsque l'utilisateur clique sur "Capture", procédez comme suit:

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

Cela ouvrira un nouvel onglet ou une nouvelle fenêtre avec la "capture d'écran", permettant à l'utilisateur de l'enregistrer. Il n'y a aucun moyen d'invoquer une sorte de dialogue 'enregistrer sous', c'est donc le mieux que vous puissiez faire, à mon avis.

77
Delan Azabani

Ceci est une extension de answer de @ Dathan, utilisant html2canvas et FileSaver.js .

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


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

Ce bloc de code attend que le bouton avec l'ID btnSave soit cliqué. Si tel est le cas, il convertit la widget div en un élément de canevas puis utilise l'interface saveAs () FileSaver (via FileSaver.js dans les navigateurs qui ne la prend pas en charge de manière native) pour enregistrer la div sous une image nommée "Dashboard.png". . 

Un exemple de ce travail est disponible sur ce fiddle .

72
Andy

Après des heures de recherche, j’ai finalement trouvé une solution pour prendre une capture d’écran d’un élément, même si le Origin-clean FLAG est défini (pour empêcher XSS), c’est pourquoi vous pouvez même capturer, par exemple, Google Maps (dans mon cas). J'ai écrit une fonction universelle pour obtenir une capture d'écran. La seule chose dont vous avez besoin en plus est la bibliothèque html2canvas ( https://html2canvas.hertzen.com/ ).

Exemple:

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);
}

N'oubliez pas que console.log() et alert() ne génèrent pas de sortie si la taille de l'image est grande.

Une fonction:

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
    });
}
7
orange01

Si vous souhaitez avoir le dialogue "Enregistrer sous", il suffit de passer l'image dans un script php, qui ajoute les en-têtes appropriés

Exemple de script "tout-en-un" 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>
6
shukshin.ivan
var shot1=imagify($('#widget')[0], (base64) => {
  $('img.screenshot').attr('src', base64);
});

Jetez un coup d'œil à htmlshot package, puis vérifiez attentivement la section côté client

npm install htmlshot
3
Abdennour TOUMI

Vous ne pouvez pas prendre une capture d'écran: ce serait un risque de sécurité irresponsable de vous laisser faire. Cependant, vous pouvez:

  • Faire les choses côté serveur et générer une image
  • Dessinez quelque chose de similaire à un canevas et convertissez-le en image (dans un navigateur qui le supporte)
  • Utilisez une autre bibliothèque de dessins pour dessiner directement sur l'image (lent, mais fonctionnerait avec n'importe quel navigateur)
3
bgw
<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>

devis

1
fallen.lu

Une autre alternative consiste à utiliser API JavaScript de GrabzIt. Tout ce que vous avez à faire est de passer le sélecteur CSS de la div que vous souhaitez capturer. Il va ensuite créer une capture d'écran de cette 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>

Il y a plus d'exemples ici en train de résoudre comment capturer des éléments HTML . Pour une divulgation complète, je suis le créateur de l'API.

1
GrabzIt

Autant que je sache, vous ne pouvez pas faire cela, je peux me tromper. Cependant, je le ferais avec php, générerais un fichier JPEG en utilisant les fonctions standard php, puis afficherais l'image, ne devrait pas être un travail très difficile, mais cela dépend de la façon dont le contenu de la DIV est flashy.

0

C'est très simple, vous pouvez utiliser ce code pour capturer la capture d'écran d'une zone particulière .__, vous devez définir l'identifiant div dans html2canvas. J'utilise ici 2 div-:

div id = "voiture"
div id = "chartContainer"
si vous voulez capturer uniquement des voitures, utilisez car je ne capture que car vous pouvez changer chartContainer pour capturer le graphique html2canvas ($ ('# car') copier et coller ce code

<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>

0
Rudra Pratap Singh