web-dev-qa-db-ja.com

外部画像でhtml divの「スクリーンショット」を生成する方法は?

外部画像を含むHTML divがあります。 (以下は一例ですが、実際にはAmazon S3を使用しているため、同じサーバーにイメージをダウンロードして保存することはオプションではありません)現在、divを変換するために html2canvas を使用しています画像。ただし、外部イメージは常に空白スペースに置き換えられます。

画像をキャプチャするために使用するコード:

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

                // Convert and download as image 
                Canvas2Image.saveAsPNG(canvas); 
                $("#img-out").append(canvas);
            }
        });
    });
}); 

編集済み:jsfiddle: https://jsfiddle.net/0y2zxxL8/3/

他のライブラリを使用する場合があります。私もバックエンドでそれを行うことがあります。 (私はPHP + + laravel 5をバックエンドに使用しています)外部画像でHTML divの「スクリーンショット」を生成する方法はありますか?

Update現在の回答は編集後に機能しています。しかし、実際の使用では、ユーザーがドラッグアンドドロップで位置を設定した複数の画像があります。私はまだ位置を取得できますが、特に位置を設定しないことが可能であれば、私にとっては良いでしょう。

17
cytsunny

JSFiddle 与えられたReferenceError: Canvas2Image is not defined [PNGを保存]ボタンを押しながら。したがって、同じエラーについてコード(フィドルではない)を確認してください。

[〜#〜] update [〜#〜]
これを参照してください JSFiddle 参照例これがあなたを助けますように。

更新2
私はあなたのコードにいくつかのコードを配置し、チェックアウトします。これがあなたのソリューションになることを願っています。

FF v44での作業結果とその動作。 JSFiddle code enter image description here

$(function() { 
    $("#btnSave").click(function() { 
        html2canvas($("#widget"), {
            onrendered: function(canvas) {
                var context=canvas.getContext("2d"); // returns the 2d context object
                var img=new Image() //creates a variable for a new image

                img.src= "http://lorempixel.com/400/200/"; // specifies the location of the image
                context.drawImage(img,0,50); // draws the image at the specified x and y location
                // Convert and download as image 
                theCanvas = canvas;
                document.body.appendChild(canvas);

                // Convert and download as image 
                Canvas2Image.saveAsPNG(canvas); 
                $("#img-out").append(canvas);
            }
        });
    });
});

更新3(2016年12月29日) JSFiddle

調査の結果、問題は、データを取得するためにブラウザにメッセージを渡すだけである画像ソースのみを割り当てるためであることがわかりました。

他の画像要素は、クリックしてキャンバスを描画するときにブラウザで実際にアクセスできない場合があります。コードをロードするように指示するだけで完了です。

OPが直面しているchrome以下のような問題を解決するためにコードを変更します。

img.onload = function() {
  context.drawImage(img, 0, 50);// draws the image at the specified x and y location
}

UPDATE 4JSFiddle
OP要件に基づいて画像の位置を動的にします。

画像ソースをスキャンして外部URLを探し、それらをWebサイトに変更して、PHPでロードしてみてください。

何かのようなもの

$(function() { 

  var imageproxy = "http://example.com/imageproxy.php"; //Change this
  var mydomain = new RegExp(location.Host);

  $("#btnSave").click(function() { 

    $("#widget").find('img').each(function(){

       var img_src = $(this).attr('src');
       if(!mydomain.test(img_src)){
           $(this).attr('src', imageproxy + "?url=" + encodeURIComponent(img_src));
       }
    });

    html2canvas($("#widget"), {
        onrendered: function(canvas) {

            var link = $('<a target="_blank">Download</a>');
            link.attr('download', 'test.png');
            link.attr('href', canvas.toDataURL());

            $("#btnSave").after(link);
        }
    });
  });
}); 

imageproxy.php

<?php

if(!empty($_GET['url'])){

    $url = urldecode($_GET['url']);
    $img_type = "image/jpeg";

    $chunks = explode('.', $url);

    if(is_array($chunks) && count($chunks) > 1){
        $ext = end($chunks);

        switch ($ext){

            case 'jpg':
            case 'jpeg':
                $img_type = "image/jpeg";
            break;

            case 'png':
                $img_type = "image/png";
            break;

            case 'gif':
                $img_type = "image/gif";
            break;
        }
    }


    $img = file_get_contents($url);

    header ("Content-Type: $img_type");
    echo $img;
}

注:phpスクリプトは非常に単純で、画像検出は100%動作していません。これは単にアイデアを与えるためのものです。いくつかのphpイメージライブラリを使用してイメージタイプをロードおよび取得する場合は、数行のコードでこれを実行できます。 「php readfile」で試すこともできます。

2
sulest

onrenderedは機能しなくなりました。

「allowTaint」オプションを追加してこの問題を解決しました

{ allowTaint: true }

2018年のソリューション:

html2canvas(document.getElementById('result'), { allowTaint: true }).then(function (canvas) {
    document.body.appendChild(canvas);
});
1
r3mus