web-dev-qa-db-ger.com

JavaScript-Pipette (Farbe des Pixels unter dem Mauszeiger angeben)

Ich suche ein " Eyedropper " - Tool, das mir den Hex-Wert des Pixels angibt, unter dem sich der Mauszeiger befindet, in JavaScript für ein CMS.

Für Firefox gibt es die hervorragende Erweiterung ColorZilla , die genau das tut. Es ist jedoch nur FF, und ich würde das Tool gerne zusammen mit dem CMS ausliefern.

Ein niederländischer Entwickler hatte die sehr clevere Idee eine Kombination aus Ajax und PHP's imagecolorat() zu verwenden Finden Sie die Pixelfarbe auf einem Bild heraus. Aber das schränkt den Bereich auf Bilder ein, auf die ich serverseitig zugreifen kann , und ich träume wirklich von einem universellen Tool.

Ich werde mit einem dieser Ansätze arbeiten, würde aber einen browserübergreifenden, Javascript- oder Flash-basierten Weg bevorzugen, der kein serverseitiges Fiddeln und keine Installation von Erweiterungen erfordert.

Ich interessiere mich auch für IE spezifische Lösungen, die das tun, was ColorZilla kann - ich könnte mit der Unterstützung von IE und FF leben, obwohl eine browserübergreifende Lösung dies tun würde natürlich sei ideal.

66
Pekka 웃

Mit JavaScript ist dies nicht möglich, da dies gegen die domänenübergreifende Sicherheit verstößt. Es wäre sehr schlecht, wenn Sie wüssten, aus welchen Pixeln das Bild besteht, http://some-other-Host/yourPassword.png. Sie können die Farbe des Pixels unter der Maus nur erkennen, wenn sich die Maus über einer Zeichenfläche oder einem Bildelement derselben Domäne (oder einem Bildelement einer anderen Domäne, die mit einem Access-Control-Allow-Origin: * - Header bedient wird) befindet. Im Falle der Zeichenfläche würden Sie canvasElement.getContext('2d').getImageData(x, y, 1, 1).data ausführen. Im Falle der Bilder müssten Sie sie auf eine Leinwand zeichnen mit:

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

Verwenden Sie dann einfach die zuvor für Leinwände erläuterte Methode. Wenn Sie in der Lage sein müssen, Farbwerte in verschiedene Darstellungen zu konvertieren, versuchen Sie es mit meiner color.js Bibliothek.

Außerdem werden Sie nie in der Lage sein, IE <9 (dies setzt voraus, dass IE9 Canvas unterstützt) zu unterstützen, und die Verwendung von Flash wird nicht helfen, da es die Pixeldaten von nicht lesen kann Dokument entweder.

73
Eli Grey

Mit einer Technik namens Browser Timing Attack ist es möglich, die Farbe jedes Pixels zu bestimmen (sortieren), auch auf iframes.

Grundsätzlich misst diese Technik die Zeit zum Rendern eines SVG-Filters für ein Element und nicht die Farbe selbst (requestAnimationFrame() ermöglicht die Zeitmessung mit einer viel besseren Genauigkeit als setTimeout()). Abhängig von der aktuellen Pixelfarbe benötigt der Filter mehr oder weniger Zeit, um angewendet zu werden. Auf diese Weise können Sie feststellen, ob ein Pixel dieselbe Farbe wie eine bekannte Farbe hat - beispielsweise Schwarz oder Weiß.

Weitere Details in diesem Whitepaper (pdf): http://www.contextis.com/documents/2/Browser_Timing_Attacks.pdf

Übrigens: Ja, dies ist eine Sicherheitslücke im Browser, aber ich sehe nicht, wie Browser-Anbieter sie patchen können.

14

Beim Zusammenführen verschiedener Referenzen, die hier in StackOverflow und auf anderen Websites zu finden sind, habe ich Javascript und JQuery verwendet:

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

Dies ist meine vollständige Lösung. Hier habe ich nur Canvas und ein Bild verwendet, aber wenn Sie <map> Über dem Bild verwenden müssen, ist dies auch möglich. Ich hoffe ich habe geholfen.

11
ebragaparah

Ich stimme der sehr detaillierten Antwort von Elijah zu. Außerdem würde ich sagen, dass Sie die Leinwand nicht benötigen, wenn es um Bilder geht. Wie Sie selbst angegeben haben, haben Sie diese Bilder in PHP verfügbar und können die Farbabfrage auf dem Server durchführen.

Ich würde vorschlagen, dass Sie dieses Problem mit einem externen Tool lösen - dies macht es sogar browserunabhängig (aber betriebssystemabhängig): Schreiben Sie ein kleines Tool (zum Beispiel in c #), das die Farbabfrage für Sie erledigt, mit einer Verknüpfung aufgerufen und übermittelt wird die Farbe auf Ihrem Server. Stellen Sie das Tool als Download auf Ihrem CMS zur Verfügung.

Ein weiterer Ansatz für ein CMS war das "Stehlen" von Farben durch Analysieren des CSS: Der Anwendungsfall bestand darin, die Farben einer bereits vorhandenen Website als Farbpalette für meine Anwendung verfügbar zu machen:

  • Ich habe den Benutzer gebeten, eine URL vom Zielsystem anzugeben - hauptsächlich die Homepage des Unternehmens
  • Ich habe die Seite analysiert, um alle Farbdefinitionen in allen Inline-Stilen und verknüpften Stilen zu finden
  • (Sie können dies problemlos auf alle referenzierten Bilder ausweiten.)
  • das Ergebnis war eine schöne Farbpalette mit allen verfügbaren Farben

Vielleicht ist das auch eine Lösung für Ihr CMS?

7
rdmueller

Siehe neue Eingabe [type = color] HTML5-Element: http://www.w3.org/TR/html-markup/input.color.html , http: // demo. hongkiat.com/html5-form-input-type/index2.html .

Jetzt funktioniert es zumindest in Chrome (getestet in Ubuntu, sollte auch für Windows funktionieren). Startet den Farbauswahldialog vom Betriebssystem bereitgestellt. Wenn sich in diesem Dialogfeld eine Pipette befindet (dies ist für Gnome), können Sie eine Farbe auswählen von jedem Punkt auf Ihrem Bildschirm. Noch nicht browserübergreifend, aber sauber und standardbasiert.

4
tema

Ich weiß nicht, ob dies machbar ist, aber wenn Ihre Seiten statisch sind, können Sie einen Screenshot von jeder Seite speichern (oder vielleicht einen für jeden Browser/jede Bildschirmauflösung?) Und dann AJAX verwenden Senden Sie die Cursor-Koordinaten an den Server und geben Sie die Pixelfarbe mit PHPs imagecolorat() zurück.

Zum Aufnehmen der Screenshots können Sie Selenium IDE wie beschrieben hier verwenden.

Ich hoffe es hilft.

4
jbochi

Aus Sicherheitsgründen können Sie keine Bildschirmpixel mit Javascript erfassen (Entwickler können also keine Momentaufnahmen Ihrer persönlichen Daten machen), aber Sie KÖNNEN dies in Flash tun - Sie können Pixeldaten im Flash-Container mithilfe der flash.display abrufen .BitmapData-Klasse.

Check out http://www.sephiroth.it/tutorials/flashPHP/print_screen/ - Ich habe es in Flash-basierten WYSYWIG-Projekten verwendet, um Bilder auf einem LAMP (PHP) -Server zu speichern.

Das Problem bei der Verwendung von Flash ist, dass es auf iOS-Geräten, die derzeit sehr beliebt sind und für die es sich zu entwickeln lohnt, nicht nativ unterstützt wird. Der Blitz ist auf dem Weg durch die Röhren.

Die Canvas-basierte Methode wird sicherlich eine gute sein, vorausgesetzt, alle Ihre Besucher verfügen über aktuelle Webbrowser, die das Canvas-Tag und JavaScript unterstützen.

3
supershwa

Zu den vorherigen Antworten hinzufügen -

Eine Möglichkeit, dieses Problem in Betracht zu ziehen, besteht darin, dass Sie in der Lage sein möchten, eine 1 x 1 Pixel große Region auf dem Bildschirm aufzunehmen. Eine ziemlich verbreitete Technik zum Erfassen von Bildschirmbereichen (beispielsweise aus webbasierten Fehlerberichterstattungssystemen) besteht darin, ein signiertes Java-Applet und Java.awt.Robot zum Erfassen des Bildes zu verwenden. Wenn Sie das Applet signieren, erhalten Ihre Benutzer das Dialogfeld "Vertrauen Sie dieser App?" (Mit dem Kontrollkästchen "Apps von diesem Publisher immer vertrauen") und können das Tool dann verwenden.

Sie können das Ergebnis dann mit LiveConnect an JavaScript weitergeben (die Dokumente sind alt, aber Java Applets unterstützen dies weiterhin), oder Sie können es auf Ihrem Server veröffentlichen. Ebenso können Sie das Applet Java aus JavaScript aufrufen.

3

Es gibt keine eingebaute DOM-Methode, um generisch die Farbe eines DOM-Elements abzurufen (außer Bildern oder einem <canvas>) an einer bestimmten Pixelstelle.

Dazu müssen wir beispielsweise HTML2Canvas oder DOM Panda verwenden, um einen "Screenshot" unserer Website zu erstellen, die Klickposition des Benutzers abzurufen und die Pixelfarbe des "Screenshots" an diesem bestimmten Ort.

Mit HTML2Canvas (Version 0.5.0-beta3) können Sie Folgendes tun:

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

Demo

2
Zach Saucier