web-dev-qa-db-fra.com

Les toiles souillées ne peuvent pas être exportées

Je veux sauver ma toile à un img. J'ai cette fonction:

function save() {
    document.getElementById("canvasimg").style.border = "2px solid";
    var dataURL = canvas.toDataURL();
    document.getElementById("canvasimg").src = dataURL;
    document.getElementById("canvasimg").style.display = "inline";
}

Cela me donne une erreur:

Uncaught SecurityError: Impossible d'exécuter 'toDataURL' sur 'HTMLCanvasElement': les canevas souillées ne peuvent pas être exportées.

Que devrais-je faire?

146
user3465096

Pour des raisons de sécurité, votre disque local est déclaré "other-domain" et va altérer le canevas.

(C'est parce que vos informations les plus sensibles sont probablement sur votre disque local!).

Pendant les tests, essayez ces solutions de contournement:

  • Placez tous les fichiers liés à la page (.html, .jpg, .js, .css, etc.) sur votre bureau (pas dans des sous-dossiers).

  • Publiez vos images sur un site prenant en charge le partage inter-domaines (tel que dropbox.com). Assurez-vous de placer vos images dans le dossier public de Dropbox et d'activer le drapeau d'origine lors du téléchargement de l'image (var img = new Image (); img.crossOrigin = "anonymous" ...)

  • Installez un serveur Web sur votre ordinateur de développement (IIS et PHP serveurs Web ont tous deux des éditions gratuites qui fonctionnent parfaitement sur un ordinateur local).

150
markE

Dans la balise img, définissez crossorigin sur Anonymous.

<img crossorigin="anonymous"></img>
108
Annia Martinez

Dans mon cas, je dessinais sur une balise de toile à partir d'une vidéo. Pour remédier à l'erreur de toile corrompue, je devais faire deux choses:

<video id="video_source" crossorigin="anonymous">
    <source src="http://crossdomain.example.com/myfile.mp4">
</video>
  • Assurez-vous que l'en-tête Access-Control-Allow-Origin est défini dans la réponse de la source vidéo (configuration appropriée de crossdomain.example.com).
  • Définissez la balise video avec crossorigin = "anonymous"
12
jdramer

Si quelqu'un voit ma réponse, vous êtes peut-être dans cet état:

1. Essayer d'obtenir une capture d'écran de la carte dans la zone de dessin à l'aide de la couche ouverte 3 ou 4
2. Et vu l'exemple de exportation de la carte
3. Utilisation de ol.source.XYZ pour rendre la couche de carte

Bingo!

Utiliser ol.source.XYZ.crossOrigin = 'Anonymous' pour résoudre votre confusion. Ou comme le code suivant:

     var baseLayer = new ol.layer.Tile({
         name: 'basic',
         source: new ol.source.XYZ({
             url: options.baseMap.basic,
             crossOrigin: "Anonymous"
         })
     });
11
sknight

Si vous utilisez la fonction ctx.drawImage(), vous pouvez effectuer les opérations suivantes:

var img = loadImage('../yourimage.png', callback);

function loadImage(src, callback) {
    var img = new Image();

    img.onload = callback;
    img.setAttribute('crossOrigin', 'anonymous'); // works for me

    img.src = src;

    return img;
}

Et dans votre rappel, vous pouvez maintenant utiliser ctx.drawImage et l'exporter avec toDataURL

5
mehulmpt

On dirait que vous utilisez une image à partir d'une URL qui n'a pas défini l'en-tête Access-Control-Allow-Origin correct et donc le problème. Vous pouvez récupérer cette image sur votre serveur et l'obtenir auprès de votre serveur pour éviter les problèmes liés au système de surveillance CORS.

5
Prasanna Aarthi

Extraire [image activée par CORS] [1] de MDN. Fondamentalement, vous devez avoir un serveur hébergeant des images avec l'en-tête approprié Access-Control-Allow-Origin.

<IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
        <FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
            SetEnvIf Origin ":" IS_CORS
            Header set Access-Control-Allow-Origin "*" env=IS_CORS
        </FilesMatch>
    </IfModule>
</IfModule>

Vous pourrez enregistrer ces images sur le stockage DOM comme si elles avaient été servies à partir de votre domaine, sans quoi vous auriez un problème de sécurité.

var img = new Image,
    canvas = document.createElement("canvas"),
    ctx = canvas.getContext("2d"),
    src = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"; // insert image url here

img.crossOrigin = "Anonymous";

img.onload = function() {
    canvas.width = img.width;
    canvas.height = img.height;
    ctx.drawImage( img, 0, 0 );
    localStorage.setItem( "savedImageData", canvas.toDataURL("image/png") );
}
img.src = src;
// make sure the load event fires for cached images too
if ( img.complete || img.complete === undefined ) {
    img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
    img.src = src;
}
3
BerlinaLi