web-dev-qa-db-ja.com

汚染されたキャンバスはエクスポートできません

キャンバスをimgに保存したいです。私はこの機能があります。

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

それは私にエラーを与えます:

セキュリティエラーが検出されました: 'HTMLCanvasElement'で 'toDataURL'を実行できませんでした:汚染されたキャンバスはエクスポートできません。

私は何をすべきか?

137
user3465096

セキュリティ上の理由から、あなたのローカルドライブは "other-domain"であると宣言されており、キャンバスを汚染するでしょう。

(それはあなたの最も機密性の高い情報があなたのローカルドライブにある可能性が高いからです!).

テスト中に次の回避策を試してください。

  • すべてのページ関連ファイル(.html、.jpg、.js、.cssなど)をデスクトップ(サブフォルダではない)に置きます。

  • 画像をクロスドメイン共有をサポートするサイト(dropbox.comなど)に投稿してください。画像をダウンロードするときは必ず画像をdropboxのパブリックフォルダに置き、クロスOriginフラグを設定してください(var img = new Image(); img.crossOrigin = "anonymous" ...)。

  • 開発用コンピュータにWebサーバーをインストールします(IISとPHP Webサーバーはどちらも、ローカルコンピュータでうまく動作する無料版を持っています)。

143
markE

imgタグ内でcross Originを匿名に設定します

<img crossOrigin="Anonymous"></img>
101
Annia Martinez

私の場合は、ビデオからキャンバスタグに描画していました。汚染されたキャンバスエラーに対処するために、私は2つのことをしなければなりませんでした:

<video id="video_source" crossorigin="anonymous">
    <source src="http://crossdomain.example.com/myfile.mp4">
</video>
  • Access-Control-Allow-Originヘッダーがビデオソースの応答に設定されていることを確認します(crossdomain.example.comの適切な設定)。
  • Crossorigin = "anonymous"を持つようにビデオタグを設定します
12
jdramer

誰かが私の答えを見れば、あなたはたぶんこの状態にある:

1。 openlayers 3または4を使用してキャンバスで地図のスクリーンショットを取得しようとしています
2。そして地図をエクスポートする 例を見ました
3。 ol.source.XYZを使用してマップ画層をレンダリングする

ビンゴ!

あなたの混乱を解決するためにol.source.XYZ.crossOrigin = '匿名'を使ってください。あるいは次のようなコードです。

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

ctx.drawImage()関数を使っている場合は、次のことができます。

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

そしてコールバックではctx.drawImageを使うことができ、toDataURLを使ってそれをエクスポートすることができます

4
mehulmpt

正しいAccess-Control-Allow-Originヘッダーを設定していないURLからの画像を使用しているように見えます。そのため、サーバーからその画像を取得してCORSの問題を回避するためにサーバーから取得できます。

4
Prasanna Aarthi

MDNから[CORS対応イメージ] [1]をチェックしてください。基本的に、適切な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>

あなたはそれらがあなたのドメインから提供されたかのようにDOM Storageにそれらの画像を保存することができるでしょう。そうでなければあなたはセキュリティ問題にぶつかるでしょう。

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;
}
2
BerlinaLi