जावास्क्रिप्ट के साथ एक div का स्क्रीनशॉट कैसे लें?


175

मैं "HTML क्विज़" नामक कुछ का निर्माण कर रहा हूं। यह पूरी तरह से जावास्क्रिप्ट पर चलता है और यह बहुत अच्छा है।

अंत में, एक परिणाम बॉक्स पॉप अप करता है जो कहता है कि "आपका परिणाम:" और यह दर्शाता है कि उन्हें कितना समय लगा, उन्हें कितना प्रतिशत मिला, और उन्हें कितने प्रश्न सही मिले। 10. मैं एक बटन रखना चाहूंगा जो कहता है "परिणामों को कैप्चर करें" और इसे किसी तरह स्क्रीनशॉट या डिव का कुछ ले लें, और फिर पृष्ठ पर कैप्चर की गई छवि दिखाएं जहां वे राइट क्लिक कर सकते हैं और "इमेज को सेव करें।"

मैं वास्तव में ऐसा करना पसंद करूंगा ताकि वे अपना परिणाम दूसरों के साथ साझा कर सकें। मैं उन्हें परिणामों को "कॉपी" नहीं करना चाहता क्योंकि वे आसानी से बदल सकते हैं। यदि वे छवि में जो कहते हैं उसे बदल देते हैं, ओह ठीक है।

क्या कोई ऐसा करने का तरीका जानता है या कुछ इसी तरह का?


2
Phantomjs.org पर एक नजर है । इसका उपयोग करके आप सर्वर पर HTML पेज की पूरी छवि तैयार कर सकते हैं, और उपयोगकर्ता को डाउनलोड करने के लिए एक लिंक दे सकते हैं।
जोशुआ

छवि बदलने और डाउनलोड करने के लिए codepedia.info/…
singh

जवाबों:


98

नहीं, मुझे किसी तत्व को 'स्क्रीनशॉट' करने के तरीके का पता नहीं है, लेकिन आप जो कर सकते हैं, वह एक कैनवास तत्व में क्विज़ के परिणाम को आकर्षित करता है, फिर छवि की सामग्री के साथ एक यूआरआई प्राप्त करने के लिए HTMLCanvasElementऑब्जेक्ट के toDataURLफ़ंक्शन का उपयोग करें data:

जब प्रश्नोत्तरी समाप्त हो जाए, तो यह करें:

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

जब उपयोगकर्ता "कैप्चर" पर क्लिक करता है, तो यह करें:

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

यह 'स्क्रीनशॉट' के साथ एक नया टैब या विंडो खोलेगा, जिससे उपयोगकर्ता इसे सहेज सकेगा। तरह-तरह के 'सेव एज़' डायलॉग को इनवाइट करने का कोई तरीका नहीं है, इसलिए मेरी राय में आप यही कर सकते हैं।


धन्यवाद!! मैं कैनवास के बारे में कुछ नहीं जानता, लेकिन मैं इसे सीखूंगा। मैं कैनवास 2 डी ड्राइंग प्रभाव का उपयोग कैसे करूंगा? क्या आप इसमें मेरी सहायता कर सकते हैं? बहुत बहुत धन्यवाद! :)
नाथन

5
मोज़िला के दस्तावेज़ों को आज़माएं, यह पालन करना वास्तव में बहुत आसान है: developer.mozilla.org/en/canvas_tutorial
Delan Azabani

एक नई विंडो / टैब में खोलने के बजाय, क्या मैं इसे इनलाइन डायलॉग बॉक्स में खोल सकता हूं? (फैंसीबॉक्स लाइटबॉक्स प्लगइन की तरह?)
नाथन

हां, आपके पास एक इनलाइन डायलॉग बॉक्स हो सकता है, imgजिसका srcसेट data:URI के पास है। हालाँकि, यह वास्तव में आवश्यक नहीं है - आप केवल canvasइनलाइन संवाद बॉक्स में ही डाल सकते हैं ; उपयोगकर्ता इसे राइट-क्लिक कर सकते हैं और छवि के रूप में वर्तमान स्थिति को बचा सकते हैं।
डेलन अजाबनी

धन्यवाद :) मैं छवि संस्करण का उपयोग कर सकता हूं ताकि वे "छवि के रूप में सहेजें" पर क्लिक करें और क्लिक कर सकें
नाथन

89

यह html2canvas और FileSaver.js का उपयोग करते हुए @ दातान के उत्तर का विस्तार है ।

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


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

यह कोड ब्लॉक बटन पर क्लिक किए जाने वाले आईडी btnSaveका इंतजार करता है । जब यह है, यह धर्मान्तरितwidget div को एक कैनवास तत्व में कनवर्ट करता है और फिर "डैशबोर्ड .png" नामक छवि के रूप में div को बचाने के लिए SaveS () FileSaver इंटरफ़ेस (ब्राउज़र में FileSaver.js जो इसे इसका समर्थन नहीं करते हैं) का उपयोग करता है।

इस काम का एक उदाहरण इस फिडेल पर उपलब्ध है ।


7
मुझे संदर्भ जोड़ने की आवश्यकता है: html2canvas, filesaver, blob, कैनवस -Blob। उसके बाद इसने काम किया। धन्यवाद!
सिरथोमास

1
बहुत बढ़िया, यह स्वीकृत उत्तर होना चाहिए। सीधा प्लग एन प्ले।
rgshenoy

क्या आप जानते हैं कि यह तीन .js के साथ कैसे काम करेगा? मेरे पास एक div है जो तीन.js रेंडरर / कैनवस (रेंडरर.डोमेमेंट) में है, और फिर उसके ऊपर divs है। मैं मूल DIV का स्नैपशॉट लेना और सब कुछ कैप्चर करना चाहूंगा? क्या यह संभव है? धन्यवाद!
रैंकस्टिनडियो

1
क्या आप अपने DOM में दिखने वाली इमेज से बच सकते हैं? क्या यह सीधे डाउनलोड करने के लिए नहीं जा सकता?
कुलन

1
यह पहली कोशिश पर मेरे लिए बहुत अच्छा काम किया, और यहां तक ​​कि मूल सीएसएस स्टाइलिंग आदि को आश्चर्यजनक रूप से सटीक लगता है। सटीकता के इस स्तर के साथ एक आभासी स्क्रीन-शॉट बहुत ज्यादा है। मैंने उन 2 पुस्तकालयों के लिए CDN का उपयोग किया है जिन्हें मुझे जोड़ना था: <! - html2canvas -> <script src = " cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1// ... <-! Filesaver -! > <स्क्रिप्ट src = " cdn.jsdelivr.net/npm/file-saver@2.0.2/dist/… >
OG सीन

13

घंटों के शोध के बाद, मुझे आखिरकार एक तत्व का स्क्रीनशॉट लेने का एक समाधान मिला, भले ही origin-cleanFLAG सेट हो (XSS को रोकने के लिए), यही कारण है कि आप उदाहरण के लिए Google मैप्स पर भी कब्जा कर सकते हैं (मेरे मामले में)। मैंने स्क्रीनशॉट लेने के लिए एक सार्वभौमिक फ़ंक्शन लिखा। इसके अलावा आपको केवल एक चीज की आवश्यकता है html2canvas लाइब्रेरी ( https://html2canvas.hertzen.com/ )।

उदाहरण:

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

ध्यान रखें console.log()और alert()अगर छवि का आकार बहुत अच्छा है तो आउटपुट नहीं मिलेगा।

समारोह:

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

जहाँ आपने html2canvas फ़ंक्शन को परिभाषित किया है
भारती

मैं फ़ंक्शन को प्राप्त करने से पहले पुस्तकालय html2canvas (मेरी पोस्ट में लिंक देखें) को एकीकृत कर चुका हूं। उदाहरण के लिए <script> -tag। बस html2canvas डाउनलोड करें और इसे अपने प्रोजेक्ट में कॉपी करें।
नारंगी 01

@ Orange01 - मैं अभी भी गूगल मैप के स्ट्रीट लेन पर कब्जा नहीं कर पा रहा हूं। यह केवल ज़ूम इन और आउट बटन, मैप और सैटेलाइट टेक्स्ट को स्क्रीनशॉट करता है। क्या आप पूर्ण मानचित्र पर कब्जा करने में मदद कर सकते हैं। धन्यवाद
फरहान साहिबोल

7

यदि आप "सेव एज़" डायलॉग रखना चाहते हैं, तो बस इमेज को 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>

3

आप एक स्क्रीन-शॉट नहीं ले सकते: ऐसा करने के लिए यह एक गैर-जिम्मेदार सुरक्षा जोखिम होगा। हालाँकि, आप कर सकते हैं:

  • सर्वर-साइड चीजें करें और एक छवि बनाएं
  • कैनवस के समान कुछ बनाएं और उसे एक छवि के लिए प्रस्तुत करें (एक ब्राउज़र में जो इसका समर्थन करता है)
  • छवि पर सीधे खींचने के लिए कुछ अन्य ड्राइंग लाइब्रेरी का उपयोग करें (धीमा, लेकिन किसी भी ब्राउज़र पर काम करेगा)

धन्यवाद! मैं कैनवास के साथ जाऊंगा, क्योंकि मुझे किसी "ड्राइंग लाइब्रेरी" का पता नहीं है और न ही मुझे पता है कि मुझे यह कैसे करना है। मैं कैनवास पर उतना अच्छा नहीं हूं, लेकिन मैं कोशिश करूंगा।
नाथन

2
क्षमा करें, मुझे यह टिप्पणी इसलिए करनी पड़ी क्योंकि यह गूगल से आता है लेकिन डब्ल्यूटीएफ "गैर-जिम्मेदार सुरक्षा जोखिम" मैं पूछ सकता हूं कि क्यों, अगर आप जावास्क्रिप्ट को दिए गए डोरियों के भीतर स्क्रीनशॉट या शॉट लेते हैं और BASE64 एनकोडेड डेटा को एक स्ट्रिंग के रूप में वापस करते हैं कोई सुरक्षा समस्या नहीं है
बर्कमर्ने 01

@MartinBarker I (उदाहरण के लिए) किसी के फेसबुक पेज को iframe में खींच सकता है और फिर उसे स्क्रीनशॉट कर सकता है। XSS को रोकने के लिए आम तौर पर एक क्रॉस-साइट iframe सुलभ DOM का हिस्सा नहीं है, लेकिन ब्राउज़र विक्रेता के लिए इस तरह के मामले में इसे रोकना बहुत कठिन होगा।
bgw

2
@MartinBarker जावास्क्रिप्ट उपयोगकर्ता को सूचित किए बिना भी एक दुर्भावनापूर्ण स्रोत को डेटा दे सकता है, जबकि "प्रिंट स्क्रीन" को उपयोगकर्ता द्वारा नियंत्रित किया जाता है, न कि कुछ मनमाने ढंग से अविशिष्ट वेबसाइट।
bgw

2
क्या मारपीट हुई। @PiPeep, यदि कोई वेबपेज फेसबुक के iFrame को लोड कर सकता है, तो पहले से ही अलगाव है, तो स्क्रीनशॉट एपीआई के साथ इस तरह के अलगाव को क्यों न बढ़ाया जाए? जैसे। Div.ToPNG (), जहां उपर्युक्त iFrame का उल्लेख किया गया है? यह एक गैरजिम्मेदार सुरक्षा जोखिम नहीं है, यह सिर्फ बिल्ट-इन नहीं है और किसी ने भी "संभावित" गोपनीयता / सुरक्षा मुद्दों के माध्यम से काम नहीं किया है ताकि इसे स्क्रीनशॉट स्क्रीनशॉट में बनाया जा सके। उदाहरण के लिए इंट्रानेट वेब अनुप्रयोगों के समर्थन जैसे उपयोग-मामलों के असंख्य के लिए यह बहुत उपयोगी होगा।
टॉड

3
var shot1=imagify($('#widget')[0], (base64) => {
  $('img.screenshot').attr('src', base64);
});

Htmlshot पैकेज पर एक नज़र डालें , फिर, ग्राहक पक्ष अनुभाग की गहराई से जाँच करें :

npm install htmlshot

इस htmlshot परियोजना अभी भी बनाए रखा है? Npm से github लिंक अभी भी मौजूद नहीं है। क्या इसके लिए कोई दूसरी वेबसाइट है?
whatsTheDiff

@whatsTheDiff:: मुझे अपनी आवश्यकताओं को दें, और, सुनिश्चित करें कि मैं आपकी मदद करूँगा। इस पुस्तकालय के लेखक मैं हूँ।
अब्देन्नौर TOUMI

2
शुक्रिया @ abdennour-toumi मैंने कोड के माध्यम से देखने के लिए सिर्फ एक एनपीएम इंस्टॉल किया है। ऐसा लगता है कि यह html2canvas का उपयोग कर रहा है जो मैंने कोशिश की है और IE में मुद्दों के साथ और एसवीजी के कारण और मेरे पृष्ठ की जटिलता के कारण। ऐसा प्रतीत होता है कि यह पुस्तकालय उस संबंध में मेरी मदद नहीं करेगा।
whatsTheDiff

4
आपके ग्राहक को IE से बचना होगा .. उन्हें बताएं कि!
अब्देनौर TOUMI

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

उद्धरण


1

यह सरल है कि आप इस कोड का उपयोग उस विशेष क्षेत्र के स्क्रीनशॉट पर कब्जा करने के लिए कर सकते हैं जिसे आपको html2canvas में div id को परिभाषित करना है। मैं यहाँ 2 div-:

div id = "car"
div id = "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>


1
JQuery को दो बार क्यों शामिल किया गया है, और jQuery UI को क्यों शामिल किया गया है? ईमानदारी से, jQuery की यहाँ ज़रूरत नहीं है जो मैं बता सकता हूँ। document.getElementById('car')याdocument.querySelector('#car')
नाथन

वास्तव में मैं अपने प्रोजेक्ट पर काम कर रहा हूं। तो मैं सिर्फ पुस्तकालय को हटाने के बारे में भूल जाता हूं और कुछ भी नहीं।
रुद्र प्रताप सिंह

0

जहां तक ​​मुझे पता है कि आप ऐसा नहीं कर सकते, मैं गलत हो सकता हूं। हालाँकि, मैं php के साथ ऐसा करूँगा, php मानक फ़ंक्शंस का उपयोग करके JPEG जनरेट करूँगा और फिर इमेज प्रदर्शित करूँगा, बहुत कठिन काम नहीं होना चाहिए, हालाँकि यह निर्भर करता है कि DIV की सामग्री कितनी आकर्षक है


ओपी ने कभी सुझाव नहीं दिया कि वह सर्वर-साइड प्रसंस्करण का उपयोग कर रहा है, हालांकि यदि वह था, तो यह ठीक होगा।
डेलन अजाबनी

हाँ, मैं दुर्भाग्य से सर्वर-साइड सामान का उपयोग नहीं कर सकता। मैं शायद ऊपर दिए गए उत्तर में से एक के साथ जाऊंगा। लेकिन धन्यवाद! :)
नाथन

-3

जहाँ तक मैं जानता हूँ कि यह जावास्क्रिप्ट के साथ संभव नहीं है।

हर परिणाम के लिए आप क्या कर सकते हैं एक स्क्रीनशॉट बनाएं, इसे कहीं पर सहेजें और सहेजे गए परिणाम पर क्लिक करने पर उपयोगकर्ता को इंगित करें। (मुझे लगता है कि परिणाम की कोई संख्या केवल 10 है इसलिए परिणामों की 10 एमपीईजी छवि बनाने के लिए कोई बड़ी बात नहीं है)


उत्तर देने के लिए धन्यवाद :) आप सही हैं! मैं परिणामों के केवल 10 JPG चित्र बना सकता था और फिर एक बार जब वे बटन पर क्लिक करेंगे, तो यह उनके लिए छवि दिखाएगा। एकमात्र समस्या यह है कि जब वे प्रश्नोत्तरी शुरू करते हैं, तो उन्हें अपना नाम दर्ज करना पड़ता है, और मैं इसे प्रश्नोत्तरी के माध्यम से प्रदर्शित करता हूं, और परिणाम बॉक्स में अंत में, यह उनका नाम दिखाता है और यह "गेटिंग बेटर" जैसी टिप्पणी कहता है। आदि मैं उनका नाम छवि में नहीं रख पाऊंगा या नहीं?
नाथन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.