80 votes

Pipette JavaScript (indique la couleur du pixel sous le curseur de la souris)

Je suis à la recherche d'un " compte-gouttes "qui me donne la valeur hexagonale du pixel sous lequel se trouve le curseur de la souris, en JavaScript pour un CMS.

Pour Firefox, il y a l'excellent ColorZilla qui fait exactement cela. Cependant, il ne s'agit bien sûr que de FF, et j'aimerais vraiment livrer l'outil en même temps que le CMS.

Un développeur néerlandais a eu le idée très intelligente de l'utilisation d'une combinaison d'Ajax et de la technologie PHP. imagecolorat() pour trouver la couleur du pixel sur une image. Mais cela limite l'éventail des images auxquelles je peux accéder côté serveur. et je rêve vraiment d'un outil universel.

Je suis prêt à travailler avec l'une ou l'autre de ces approches, mais je préférerais de loin une approche multi-navigateurs, basée sur Javascript ou Flash, qui ne nécessite pas de manipulation côté serveur ni d'installation d'extensions.

Je suis également intéressé par toute solution spécifique à IE qui fait ce que ColorZilla peut faire - je pourrais vivre avec la prise en charge d'IE et de FF seulement, bien qu'une solution multi-navigateurs serait bien sûr idéale.

0 votes

Ce n'est pas possible en Javascript ; je ne suis pas sûr pour Flash.

0 votes

En théorie, vous pourriez être en mesure de traiter les informations de style associées à l'élément le plus haut situé sous le curseur de la souris et de déterminer la couleur de cet élément. debe être, si elle n'est pas une image ou un canevas. En pratique, cela vous rendrait probablement fou de devoir gérer les bordures, les marges et les bizarreries des navigateurs. Je pense que la réponse d'Elijah est la seule pratique.

84voto

Eli Grey Points 17553

Ce n'est pas possible avec JavaScript car cela va à l'encontre de la sécurité inter-domaines. Ce serait très mauvais si vous saviez quels pixels composent l'image, http://some-other-host/yourPassword.png . Vous ne pouvez connaître la couleur du pixel situé sous la souris que si celle-ci se trouve au-dessus d'un canevas ou d'un élément d'image du même domaine (ou d'un élément d'image d'un autre domaine qui est servi avec une balise Access-Control-Allow-Origin: * ). Dans le cas de la toile, vous feriez canvasElement.getContext('2d').getImageData(x, y, 1, 1).data . Dans le cas des images, vous devrez les dessiner sur une toile avec :

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

Et ensuite, il suffit d'utiliser la méthode précédente expliquée pour les toiles. Si vous devez être capable de convertir en diverses représentations de valeurs de couleurs, essayez mes color.js bibliothèque.

De plus, vous ne serez jamais en mesure de prendre en charge IE <9 (en supposant qu'IE9 prenne en charge le canevas) et l'utilisation de Flash ne sera d'aucune utilité car il ne peut pas non plus lire les données en pixels du document.

5 votes

L'aspect intéressant de la sécurité, et merci pour l'angle Canvas. Cependant, je pourrais m'accommoder de ne pouvoir accéder qu'aux pixels de mon domaine.

0 votes

Merci Elijah. Je suis quelque peu attristé que cela soit limité à Firefox, mais ce n'est pas de votre faute et c'est certainement la solution la plus simple. Je vais probablement la combiner avec une option de repli côté serveur (plus lente) pour répondre aux besoins d'IE. J'accepte votre réponse.

0 votes

Je ne vois pas pourquoi cela poserait un problème de sécurité. En l'état actuel des choses, JavaScript peut accéder au texte brut d'un mot de passe à partir de n'importe quel ordinateur. input:password .

21voto

En utilisant une technique appelée Attaque de la synchronisation des navigateurs il est possible de déterminer (en quelque sorte) la couleur de n'importe quel pixel, même dans les iframes.

Fondamentalement, cette technique mesure le temps de rendu d'un filtre SVG sur un élément, plutôt que la couleur elle-même ( requestAnimationFrame() permet de mesurer le temps avec une bien meilleure précision que setTimeout() ). En fonction de la couleur actuelle du pixel, le filtre met plus ou moins de temps à s'appliquer. Il est ainsi possible de déterminer si un pixel est de la même couleur qu'une couleur connue - par exemple le noir ou le blanc.

Plus de détails dans ce livre blanc (pdf) : https://www.contextis.com/media/downloads/Pixel_Perfect_Timing_Attacks_with_HTML5_Whitepaper.pdf

À propos : oui, il s'agit d'une faille de sécurité du navigateur, mais je ne vois pas comment les fournisseurs de navigateurs peuvent la corriger.

0 votes

Cette solution est intéressante, mais n'est-elle pas sécurisée par les politiques d'origine croisée ?

0 votes

Cet article a presque 7 ans ! Quelqu'un sait-il si cette faille de sécurité subsiste encore aujourd'hui ?

0 votes

Je doute qu'il ait été corrigé et que CORS ne s'applique pas.

12voto

ebragaparah Points 131

En fusionnant diverses références trouvées ici dans StackOverflow et dans d'autres sites, je l'ai fait en utilisant javascript et 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>

Voici ma solution complète Ici je n'ai utilisé que la toile et une image, mais si vous avez besoin d'utiliser <map> sur l'image, c'est possible aussi. J'espère vous avoir aidé.

2 votes

Que diriez-vous d'utiliser le compte-gouttes pour permettre d'obtenir de la couleur de n'importe où ?

7voto

Ralf Points 4270

Je suis d'accord avec la réponse très détaillée fournie par Elijah. De plus, je dirais que vous n'avez pas besoin du canevas lorsqu'il s'agit d'images. Comme vous l'avez dit vous-même, vous avez ces images disponibles dans php et vous pouvez faire la requête de couleur sur le serveur.

Je vous suggère de traiter ce problème avec un outil externe - ce qui le rend indépendant du navigateur (mais dépendant du système d'exploitation) : écrivez un petit outil (par exemple en c#) qui fait la requête de couleur pour vous, est invoqué avec un raccourci et soumet la couleur à votre serveur. Mettez l'outil à disposition en téléchargement sur votre CMS.

Une autre approche que j'ai utilisée pour un CMS était de "voler" les couleurs en analysant le CSS : le cas d'utilisation était de rendre les couleurs d'un site web déjà existant disponibles comme palette de couleurs pour mon application :

  • J'ai demandé à l'utilisateur de fournir une URL du système cible - le plus souvent la page d'accueil de l'entreprise
  • J'ai analysé la page pour trouver toutes les définitions de couleurs dans tous les styles en ligne et les styles liés.
  • (vous pouvez facilement étendre cela à toutes les images référencées)
  • Le résultat est une belle palette de couleurs avec toutes les couleurs coporate à choisir.

Peut-être que c'est aussi une solution pour votre CMS ?

0 votes

Merci Ralf. La création d'une palette personnalisée est une très bonne idée, mais elle ne convient pas à ma tâche, car il y aura beaucoup de nouveau contenu sans gamme de couleurs définie. Une application côté client est certainement l'approche la plus propre, mais j'ai besoin d'un outil qui fonctionne à la fois sous Windows et Mac OS. Ce serait une bonne raison de me remettre à la programmation côté client (et une première fois sur Mac), mais j'ai tellement de choses à faire en ce moment. Je pense que je vais opter pour l'approche "image seulement".

5voto

jbochi Points 12280

Je ne sais pas si c'est faisable, mais si vos pages sont statiques, vous pourriez enregistrer une capture d'écran de chacune d'entre elles (ou peut-être une pour chaque navigateur/résolution d'écran ? ) et ensuite utiliser AJAX pour envoyer les coordonnées du curseur au serveur et renvoyer la couleur des pixels avec la fonction PHP imagecolorat() .

Pour faire les captures d'écran, vous pouvez utiliser IDE Selenium comme décrit aquí .

J'espère que cela vous aidera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X