JavaScriptでdivのスクリーンショットを撮る方法は?


175

「HTMLクイズ」と呼ばれるものを作成しています。JavaScriptで完全に実行されており、非常に優れています。

最後に、「あなたの結果:」という結果ボックスがポップアップし、彼らがかかった時間、得られたパーセンテージ、および彼らが10問のうち何問正解したかが表示されます。 「結果をキャプチャー」して、スクリーンショットまたはdivの何かを撮って、右クリックして「画像を別名で保存」できるページにキャプチャされた画像を表示します。

彼らが結果を他の人と共有できるように、私は本当にこれをやりたいです。結果を簡単に変更できるので、結果を「コピー」したくない。彼らがそれがイメージで言うことを変えるならば、まあ。

誰かこれを行う方法や似たようなことを知っていますか?


2
見ていphantomjs.orgを。これを使用すると、サーバーサイドでHTMLページの完全な画像を生成し、ダウンロードするためのリンクをユーザーに提供できます。
ジョシュア

画像を変換し、codepedia.info

回答:


99

いいえ、要素を「スクリーンショット」する方法はわかりませんが、クイズの結果をcanvas要素に描画し、HTMLCanvasElementオブジェクトのtoDataURL関数を使用data:して画像のコンテンツを含むURI を取得する方法があります。

クイズが終了したら、次のようにします。

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

これにより、「スクリーンショット」で新しいタブまたはウィンドウが開き、ユーザーがそれを保存できるようになります。種類の「名前を付けて保存」ダイアログを呼び出す方法はないので、これは私の意見ではあなたができる最善の方法です。


ありがとう!! キャンバスについては何も知りませんが、学びます。Canvas 2D描画効果をどのように使用しますか?これを手伝ってくれませんか?本当にありがとう!:)
ネイサン

5
Mozillaのドキュメントを試してみてください。とても簡単にフォローできます:developer.mozilla.org/en/canvas_tutorial
Delan Azabani '31

新しいウィンドウ/タブで開く代わりに、インラインダイアログボックスで開くことはできますか?(Fancyboxライトボックスプラグインのように?)
ネイサン

うん、あなたはとインラインダイアログボックス持つことができimg、その持っているものsrcにセットdata:URIを。ただし、それは必ずしも必要ではありませんcanvas。インラインダイアログボックスにそれ自体を置くだけでかまいません。ユーザーはそれを右クリックして現在の状態を画像として保存できます。
Delan Azabani、2011

ありがとう:)画像バージョンを使用すると、右クリックして[名前を付けて画像を保存]をクリックできるようになります
Nathan

89

これはhtml2canvasFileSaver.jsを使用した@Dathan回答の拡張です。

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


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

このコードブロックは、ID btnSaveを持つボタンがクリックされるのを待ちます。ある場合は、widgetdivをcanvas要素に変換し、saveAs()FileSaverインターフェイスを使用して(ネイティブでサポートされていないブラウザーのFileSaver.jsを介して)、「Dashboard.png」という名前のイメージとしてdivを保存します。

この作業の例は、このフィドルで入手できます。


7
html2canvas、filesaver、blob、canvas-toBlobへの参照を追加する必要がありました。その後それは働いた。ありがとう!
sirthomas 2014

1
すごい、これは受け入れられる答えになるはずです。簡単なプラグアンドプレイ。
rgshenoy 2016年

これがthree.jsでどのように機能するか知っていますか?three.jsレンダラー/キャンバスが含まれているdiv(renderer.domElement)があり、その上にdivがあります。親DIVのスナップショットを取り、すべてをキャプチャしますか?これは可能ですか?ありがとう!
Rankinstudio

1
DOMに画像が表示されないようにできますか?すぐにダウンロードできませんか?
kulan

1
これは私にとって最初の試みでうまく機能し、元のCSSスタイリングなどのように見えました。驚くほど正確です。このレベルの精度の仮想スクリーンショットのほとんど。追加しなければならない2つのライブラリにCDNを使用しました。<!-html2canvas-> <script src = " cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/… > <!-filesaver- > <script src = " cdn.jsdelivr.net/npm/file-saver@2.0.2/dist/… >
OG Sean

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()画像のサイズが大きい場合は出力を生成won't。

関数:

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関数を定義した場所
Bharathi

関数getScreenshotOfElement()に到達する前に、ライブラリhtml2canvas(私の投稿のリンクを参照)を統合しました。たとえば、<script>タグを使用します。html2canvasをダウンロードしてプロジェクトにコピーするだけです。
orange01 2017

@ orange01-まだGoogleマップの車線をキャプチャできません。これは、ズームインとズームアウトのボタン、地図、衛星テキストのスクリーンショットのみです。フルマップをキャプチャするのを手伝ってください。ありがとう
Farhan Sahibole 2018年

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

スクリーンショットを撮ることはできません。そうすることは無責任なセキュリティリスクになります。ただし、次のことができます。

  • サーバーサイドで物事を行い、画像を生成する
  • Canvasに似たものを描き、それを画像にレンダリングします(それをサポートするブラウザーで)
  • 他の描画ライブラリを使用して画像に直接描画する(遅いが、どのブラウザでも機能する)

ありがとう!「描画ライブラリ」についても、方法もわからないので、キャンバスを使います。キャンバスも苦手ですが、頑張ります。
ネイサン

2
グーグルから来るので申し訳ありませんが、Javascriptがスクリーンショットまたは特定のコード内のショットを撮り、そのBASE64エンコードされたデータを文字列として返す場合、セキュリティ上の問題はありません。
Barkermn01

@MartinBarker(たとえば)iframeで誰かのFacebookページをプルアップして、スクリーンショットを撮ることができます。通常、クロスサイトiframeは、XSSを防ぐためのアクセス可能なDOMの一部ではありませんが、このような場合、ブラウザーベンダーがそれを停止することははるかに困難です。
bgw 2012

2
@MartinBarker Javascriptは、ユーザーに気付かれることなくデータを悪意のあるソースに提供する可能性がありますが、「印刷画面」はユーザーによって制御され、信頼できないWebサイトではありません。
bgw

2
なんてビートだ。@ PiPeep、WebページがFacebookのiFrameをロードできる場合、すでに分離があります。その分離をスクリーンショットAPIで拡張してみませんか?例えば。前述のiFrameが塗りつぶされているDiv.ToPNG()?これは無責任なセキュリティリスクではありません。組み込みではなく、そのような組み込みのスクリーンショットAPIの開発で「潜在的な」プライバシー/セキュリティの問題に取り組んだ人はいません。これは、たとえばイントラネットWebアプリケーションのサポートなど、無数のユースケースに非常に役立ちます。
トッド

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

見てくださいhtmlshotのパッケージを、そして、深くチェックし、クライアント側のセクションを:

npm install htmlshot

このhtmlshotプロジェクトはまだ維持されていますか?npmからのgithubリンクはまだ存在していないようです。別のウェブサイトはありますか?
whatsTheDiff 2016

@whatsTheDiff::私にあなたの要件を与えてください、そして、私がこのライブラリの作者なので、私があなたを助けることを確認してください。
Abdennour TOUMI

2
@ abdennour-toumiに感謝します。コードを確認するためにnpmインストールを実行しました。それは私が試したhtml2canvasを使用しているようで、IEで問題が発生しています。SVGと私のページの複雑さのためです。そのため、このライブラリはその点で私には役に立たないようです。
whatsTheDiff 2016

4
あなたの顧客はIEを避けなければなりません。
Abdennour TOUMI 16

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 =「車」
のdivのid =「chartContainerを」
あなただけの車をキャプチャしたい場合は、次に使用する車を変更できる唯一の私はここに車キャプチャよ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が2回含まれている理由とjQuery UIが含まれている理由 正直なところ、私が言えることから、jQueryはここではまったく必要ありません。document.getElementById('car')またはdocument.querySelector('#car')
ネイサン

実際私は自分のプロジェクトに取り組んでいます。ライブラリを削除するのを忘れて、何もしません。
Rudra Pratap Singh

0

あなたがそれをすることができないことを私が知っている限り、私は間違っているかもしれません。ただし、これをphpで行い、phpの標準関数を使用してJPEGを生成してから画像を表示します。それほど難しい作業ではありませんが、DIVの内容がどれほど派手であるかに依存します。


OPは、サーバー側の処理を使用していることを示唆していませんが、使用している場合は問題ありません。
Delan Azabani、2011

ええ、残念ながら、サーバー側のものは使用できません。私はおそらく上記の答えの1つに行きます。しかし、ありがとう!:)
ネイサン

-3

私の知る限り、JavaScriptでは不可能です。

すべての結果に対して実行できることは、スクリーンショットを作成してどこかに保存し、保存結果をクリックしたときにユーザーをポイントします。(私は結果が10だけではないので、結果の10 JPEG画像を作成するのは大したことではないと思います)


答えてくれてありがとう:)そうです!結果の10個のJPG画像を作成し、ボタンをクリックすると、保存する画像が表示されます。唯一の問題は、クイズを開始するときに名前を入力する必要があることです。クイズの最後まで表示し、結果ボックスの最後に名前が表示され、「Getting Better」のようなコメントが表示されます。など私はそれらの名前を画像に入れることができないでしょうか?
ネイサン、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.