web-dev-qa-db-fra.com

Comment générer une "capture d'écran" de html div avec des images externes?

J'ai un HTML div avec des images externes. (Ce qui suit est un exemple, mais dans le cas actuel, j'utilise Amazon S3. Le téléchargement et le stockage de l'image sur le même serveur ne sont pas une option.) Actuellement, j'utilise html2canvas pour convertir le div en image. Cependant, l'image externe est toujours remplacée par un espace vide.

Le code que j'utilise pour capturer l'image:

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

Edited: jsfiddle: https://jsfiddle.net/0y2zxxL8/3/

Je peux utiliser une autre bibliothèque. Je peux aussi le faire en arrière-plan. (J'utilise PHP + laravel 5 pour le backend) Est-il possible de générer une "capture d'écran" de la div HTML avec des images externes?

Update La réponse actuelle fonctionne après modification. Pourtant, pour mon utilisation réelle, il y aura plusieurs images avec leur position définie par l'utilisateur par glisser-déposer. Je peux toujours obtenir la position, mais ce serait mieux pour moi s'il est possible de ne pas définir la position spécifiquement.

16
cytsunny

Votre JSFiddle / a donné ReferenceError: Canvas2Image is not defined tout en appuyant sur le bouton "Enregistrer PNG". Alors vérifiez votre code (pas de violon) pour la même erreur.

METTRE À JOUR
Voir ceci JSFiddle exemple comme référence. Puisse celui-ci vous aider.

UPDATE 2
Je place du code dans votre code, vérifiez-le. J'espère que ce sera votre solution ..!

Résultat fonctionnel avec FF v44 et son fonctionnement. Prise de vue avec 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);
            }
        });
    });
});

UPDATE 3 (29/12/2016) JSFiddle

Après des recherches, nous avons constaté que le problème vient du fait que nous n’affectons que la source de l’image, qui transmet uniquement un message au navigateur pour récupérer les données. 

Un autre élément d'image est peut-être pas vraiment accessible avec le navigateur lorsque vous cliquez dessus pour en tirer une toile. Nous disons simplement au code de le charger et c'est fait.

Modifiez le code pour résoudre le problème du chrome chez OP, comme ci-dessous:

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

UPDATE 4JSFiddle
Dynamiser la position de l'image en fonction des exigences de l'OP.

8

Vous pouvez essayer de scanner la source de l'image à la recherche d'URL externes, de les modifier sur votre site Web et de les charger avec php.

Quelque chose comme

$(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;
}

remarque: le script php est très simple, la détection d'image ne fonctionne pas à 100%, c'est juste pour vous donner une idée. Si vous utilisez des bibliothèques d'images php pour charger et obtenir le type d'image, vous pouvez le faire avec seulement quelques lignes de code. vous pouvez aussi essayer avec "readfile php".

1
sulest

onrendered ne fonctionne plus ..

j'ai résolu ce problème en ajoutant l'option "allowTaint"

{ allowTaint: true }

Solution 2018:

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