私のコードはローカルホストでは非常にうまく機能していますが、サイトでは機能していません。
コンソールからこのエラーが発生しました。この行.getImageData(x,y,1,1).data
:
Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-Origin data.
私のコードの一部:
jQuery.Event.prototype.rgb=function(){
var x = this.offsetX || (this.pageX - $(this.target).offset().left),y = this.offsetY || (this.pageY - $(this.target).offset().top);
if (this.target.nodeName!=="CANVAS")return null;
return this.target.getContext('2d').getImageData(x,y,1,1).data;
}
注:画像のURL(src)はサブドメインのURLからのものです
他の人が言ったように、クロスオリジンドメインからロードすることでキャンバスを「汚染」しています。
https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
ただし、以下を設定するだけでこれを防止できる場合があります。
img.crossOrigin = "Anonymous";
これは、リモートサーバーが次のヘッダーを適切に設定した場合にのみ機能します。
Access-Control-Allow-Origin "*"
「ダイレクトリンク」オプションを使用する場合の Dropboxファイル選択 は、この良い例です。 oddprints.com で使用して、リモートドロップボックスの画像URLから画像をキャンバスに移動し、画像データをサーバーに送信します。すべてJavaScriptで
.setAttribute('crossOrigin', '')
を使用し、Access-Control-Allow-Origin
ヘッダーのない304応答を回避するために、URLのクエリ文字列にタイムスタンプを追加する必要があることがわかりました。
これは私に与えます
var url = 'http://lorempixel.com/g/400/200/';
var imgObj = new Image();
imgObj.src = url + '?' + new Date().getTime();
imgObj.setAttribute('crossOrigin', '');
別のサーバーからキャンバスに画像を直接描画してからgetImageData
を使用することはできません。これはセキュリティの問題であり、キャンバスは「汚染された」と見なされます。
PHPを使用して画像のコピーをサーバーに保存し、新しい画像をロードするだけで機能しますか?たとえば、URLをPHPスクリプトに送信してサーバーに保存し、次のように新しいファイル名をjavascriptに返すことができます。
<?php //The name of this file in this example is imgdata.php
$url=$_GET['url'];
$img = file_get_contents($url);
$fn = substr(strrchr($url, "/"), 1);
file_put_contents($fn,$img);
echo $fn;
?>
PHPスクリプトを次のようなajax javascriptで使用します。
xi=new XMLHttpRequest();
xi.open("GET","imgdata.php?url="+yourImageURL,true);
xi.send();
xi.onreadystatechange=function() {
if(xi.readyState==4 && xi.status==200) {
img=new Image;
img.onload=function(){
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
img.src=xi.responseText;
}
}
その後、キャンバスでgetImageData
を使用すると、正常に機能します。
あるいは、画像全体を保存したくない場合は、xおよびy座標をPHPスクリプトに渡し、その側のピクセルのrgba値を計算できます。 PHPでそのような画像処理を行うための優れたライブラリがあると思います。
このアプローチを使用する場合は、実装の支援が必要かどうかをお知らせください。
編集:覗き見は、PHPスクリプトが公開され、インターネットが潜在的に悪用する可能性があることを指摘しました。これを処理するための無数の方法があります。最も単純な方法の1つは、ある種のURLの難読化です...
コードをローカルでテストしているときに、Chrome
でこのエラーが発生していました。 Firefox
に切り替えましたが、エラーは表示されなくなりました。別のブラウザに切り替えるのは簡単な修正かもしれません。
最初の回答で与えられたソリューションを使用している場合は、img
変数を宣言した直後にimg.crossOrigin = "Anonymous";
を追加してください(たとえば、var img = new Image();
)。
クロスオリジンドメインからロードすることにより、キャンバスを「汚染」しています。このMDN記事をご覧ください。
https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
問題は、別のドメインからの外部イメージをロードすることです。これにより、キャンバスコンテキストのデータにアクセスしようとすると、セキュリティエラーが発生します。
Matt burnsが his answer で述べているように、問題の画像がホストされているサーバーでCORSを有効にする必要がある場合があります。
サーバーがApacheの場合、VirtualHost構成または.htaccess
ファイルに次のスニペット( here から)を追加することでこれを実行できます。
<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>
... VirtualHostに追加する場合、おそらくApacheの設定も再読み込みする必要があります(たとえば、ApacheがLinuxサーバーで実行されている場合はSudo service Apache2 reload
)
私は同じ問題を抱えていましたが、私にとってはhttps:${image.getAttribute('src')}
を連結するだけで機能しました
ローカルで作業しているときに、同様の問題がありました。あなたのURLはローカルファイルへのパスになります。 file:///Users/PeterP/Desktop/folder/index.html。
私はMACにいることに注意してください。
Http-serverをグローバルにインストールすることでこれを回避しました。 https://www.npmjs.com/package/http-server
手順:
npm install http-server -g
http-server ~/Desktop/folder/
PS:ノードがインストールされていると思いますが、そうでなければ、npmコマンドをあまり実行しません。