web-dev-qa-db-ja.com

JavaScriptスポイト(マウスカーソルの下のピクセルの色を教えてください)

CMS用のJavaScriptで、マウスカーソルの下にあるピクセルの16進値を提供する「Eyedropper」ツールを探しています。

Firefoxには、まさにそれを行う優れた ColorZilla 拡張機能があります。ただし、もちろんFFのみであり、CMSと共にツールを提供したいと考えています。

オランダの開発者は、AjaxとPHPのimagecolorat()を組み合わせて使用​​する 非常に賢いアイデア を持っています。画像のピクセル色を見つけます。 しかし、それは私がサーバー側にアクセスできる画像に範囲を制限します、そして私は本当に普遍的なツールを夢見ています。

これらのアプローチのいずれかを使用しますが、サーバー側の操作や拡張機能のインストールを必要としない、クロスブラウザー、Javascript、またはFlashベースの方法を好むでしょう。

また、IE ColorZillaができることを行う特定のソリューションに興味があります-クロスブラウザソリューションでは、IEとFFのみをサポートできますが、もちろん理想的です。

66
Pekka 웃

クロスドメインセキュリティに反するため、JavaScriptでは不可能です。イメージを構成するピクセルを知っていれば、それは非常に悪いでしょう、_http://some-other-Host/yourPassword.png_。マウスがキャンバスまたは同じドメインの画像要素(または_Access-Control-Allow-Origin: *_ヘッダーで提供される別のドメインの画像要素)の上にある場合にのみ、マウスの下のピクセルの色を伝えることができます。キャンバスの場合、canvasElement.getContext('2d').getImageData(x, y, 1, 1).dataを実行します。画像の場合、次のようにしてキャンバスに描画する必要があります。

_var canvas = document.createElement("canvas");
canvas.width = yourImageElement.width;
canvas.height = yourImageElement.height;
canvas.getContext('2d').drawImage(yourImageElement, 0, 0);
_

そして、キャンバスについて説明した前の方法を使用します。色の値のさまざまな表現に変換できる必要がある場合は、私の color.js ライブラリを試してください。

また、IE <9(IE9がキャンバスをサポートしていることを前提としている)をサポートすることは決してできません。Flashを使用しても、どちらかを文書化します。

73
Eli Grey

Browser Timing Attackと呼ばれる手法を使用して、iframe上であっても、ピクセルの色を(並べ替えて)決定することが可能です。

基本的に、この手法は、色自体ではなく、要素にSVGフィルターをレンダリングする時間を測定します(requestAnimationFrame()setTimeout()よりもはるかに正確に時間を測定できます)。現在のピクセルの色に応じて、フィルターの適用には多少の時間がかかります。これにより、ピクセルが既知の色と同じ色かどうか、たとえば黒か白かを判断できます。

このホワイトペーパーの詳細(pdf): http://www.contextis.com/documents/2/Browser_Timing_Attacks.pdf

ちなみに、はい、これはブラウザのセキュリティホールですが、ブラウザベンダーがどのようにパッチを適用できるのかわかりません。

14

ここでStackOverflowや他のサイトで見つかったさまざまな参照をマージし、javascriptとJQueryを使用しました。

<html>
<body>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script src="jquery.js"></script>
<script type="text/javascript">
    window.onload = function(){
        var canvas = document.getElementById('myCanvas');
        var context = canvas.getContext('2d');
        var img = new Image();
        img.src = 'photo_Apple.jpg';
        context.drawImage(img, 0, 0);
    };

    function findPos(obj){
    var current_left = 0, current_top = 0;
    if (obj.offsetParent){
        do{
            current_left += obj.offsetLeft;
            current_top += obj.offsetTop;
        }while(obj = obj.offsetParent);
        return {x: current_left, y: current_top};
    }
    return undefined;
    }

    function rgbToHex(r, g, b){
    if (r > 255 || g > 255 || b > 255)
        throw "Invalid color component";
    return ((r << 16) | (g << 8) | b).toString(16);
    }

$('#myCanvas').click(function(e){
    var position = findPos(this);
    var x = e.pageX - position.x;
    var y = e.pageY - position.y;
    var coordinate = "x=" + x + ", y=" + y;
    var canvas = this.getContext('2d');
    var p = canvas.getImageData(x, y, 1, 1).data;
    var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
    alert("HEX: " + hex);
});
</script>
<img src="photo_Apple.jpg"/>
</body>
</html>

これが私の完全なソリューションです。ここでは、キャンバスと1つの画像のみを使用しましたが、<map>画像上で、それも可能です。お役に立てば幸いです。

11
ebragaparah

エリヤが提供した非常に詳細な答えに同意します。さらに、画像に関しては、キャンバスは不要だと思います。自分で述べたように、これらの画像はphp内から利用でき、サーバーでカラークエリを実行できます。

外部ツールでこの問題を処理することをお勧めします-これにより、ブラウザに依存しません(ただしOS依存)サーバーの色。ツールをCMSでダウンロードできるようにします。

私がCMSに使用した別のアプローチは、CSSを解析して色を「盗む」ことでした。ユースケースは、既存のWebサイトの色をアプリケーションのカラーパレットとして使用可能にすることでした。

  • ユーザーにターゲットシステム(ほとんどは会社のホームページ)からURLを提供するように依頼しました
  • ページを解析して、すべてのインラインスタイルとリンクされたスタイルのすべての色の定義を見つけました
  • (これをすべての参照画像に簡単に拡張できます)
  • 結果は、すべてのコーポレートカラーから選択できる素敵なカラーパレットでした

たぶんそれはあなたのCMSの解決策でもありますか?

7
rdmueller

新しいinput [type = color] HTML5要素を参照してください: http://www.w3.org/TR/html-markup/input.color.htmlhttp:// demo。 hongkiat.com/html5-form-input-type/index2.html

現在、少なくともChrome(Ubuntuでテスト済み、Windowsでも動作するはずです)で動作します。オペレーティングシステムによって提供される色選択ダイアログを起動します)このダイアログにスポイトがある場合(Gnome用)、画面上の任意のポイントから色を選択することができます。および標準ベース。

4
tema

これが実行可能かどうかはわかりませんが、ページが静的な場合は、各ページ(または各ブラウザー/画面解像度ごとに1つ)の画像スクリーンショットを保存し、AJAXを使用してカーソル座標をサーバーに送信し、PHPのimagecolorat()でピクセルの色を返します。

スクリーンショットを撮るには、 here のように Selenium IDE を使用できます。

それが役に立てば幸い。

4
jbochi

セキュリティ上の予防措置として、JavaScriptを使用して画面ピクセルをキャプチャすることはできません(したがって、開発者は個人データのスナップショットを取得できません)が、Flashで実行できます-flash.displayを使用してFlashコンテナー内でピクセルデータを取得できます.BitmapDataクラス。

チェックアウト http://www.sephiroth.it/tutorials/flashPHP/print_screen/ -FlashベースのWYSYWIGプロジェクトで使用して、LAMP(PHP)サーバーに画像を保存しました。

Flashの使用に関する問題は、iOSデバイスでネイティブにサポートされていないことです。iOSデバイスは、現在非常に人気があり、開発する価値があります。フラッシュがチューブに向かっています。

すべての訪問者がCanvasタグとJavaScriptをサポートする最新のWebブラウザーを持っている限り、canvasベースの方法は確かに良い方法です。

3
supershwa

前の回答に追加するには-

この問題を考える1つの方法は、1ピクセルx 1ピクセルの領域のスクリーンキャプチャを実行できるようにすることです。画面領域をキャプチャするためのかなり一般的な手法(たとえば、Webベースのバグ報告システム内から)は、署名付きJavaアプレットとJava.awt.Robotを使用して画像をキャプチャすることです。アプレットに署名すると、ユーザーは「このアプリを信頼しますか?」ダイアログ(「この発行元からのアプリを常に信頼する」チェックボックスが表示されます)を取得し、ツールを使用できるようになります。

次に、LiveConnectを使用して結果をJavaScriptに渡すことができます(ドキュメントは古いですが、Javaアプレットはまだこれをサポートしています)。または、サーバーに投稿できます。同様に、 Java JavaScriptのアプレット。

3

DOM要素の色を一般的に取得する組み込みのDOMメソッドはありません(画像または<canvas>)特定のピクセル位置。

したがって、これを行うには、 HTML2Canvas または DOM Panda のようなものを使用して、Webサイトの「スクリーンショット」を取得し、ユーザーのクリック位置を取得し、その特定の場所での「スクリーンショット」のピクセル色。

HTML2Canvas(バージョン0.5.0-beta3)を使用すると、次のようなことができます。

// Take "screenshot" using HTML2Canvas
var screenshotCanvas,
    screenshotCtx,
    timeBetweenRuns = 10,
    lastTime = Date.now();
function getScreenshot() {
    // Limit how soon this can be ran again
    var currTime = Date.now();
    if(currTime - lastTime > timeBetweenRuns) {
        html2canvas(document.body).then(function(canvas) {
            screenshotCanvas = canvas;
            screenshotCtx = screenshotCanvas.getContext('2d');
        });
        lastTime = currTime;
    }
}
setTimeout(function() { // Assure the initial capture is done
    getScreenshot();
}, 100);

// Get the user's click location
document.onclick = function(event) {
    var x = event.pageX,
        y = event.pageY;

    // Look what color the pixel at the screenshot is
    console.log(screenshotCtx.getImageData(x, y, 1, 1).data);
}


// Update the screenshot when the window changes size
window.onresize = getScreenshot;

デモ

2
Zach Saucier