web-dev-qa-db-fra.com

Obtenir la couleur de pixel de la toile, au passage de la souris

Est-il possible d'obtenir le pixel de valeur RVB sous la souris? Y at-il un exemple complet de cela? Voici ce que j'ai jusqu'à présent:

<script>
function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  var img = new Image();
  img.src = 'Your URL';

  img.onload = function(){
    ctx.drawImage(img,0,0);


  };

  canvas.onmousemove = function(e) {
        var mouseX, mouseY;

        if(e.offsetX) {
            mouseX = e.offsetX;
            mouseY = e.offsetY;
        }
        else if(e.layerX) {
            mouseX = e.layerX;
            mouseY = e.layerY;
        }
        var c = ctx.getImageData(mouseX, mouseY, 1, 1).data;

        $('#ttip').css({'left':mouseX+20, 'top':mouseY+20}).html(c[0]+'-'+c[1]+'-'+c[2]);
  };
}

</script>
69
vince83000

Voici un exemple complet et autonome. Tout d'abord, utilisez le code HTML suivant:

<canvas id="example" width="200" height="60"></canvas>
<div id="status"></div>

Le JavaScript pertinent:

// set up some sample squares
var example = document.getElementById('example');
var context = example.getContext('2d');
context.fillStyle = "rgb(255,0,0)";
context.fillRect(0, 0, 50, 50);
context.fillStyle = "rgb(0,0,255)";
context.fillRect(55, 0, 50, 50);

$('#example').mousemove(function(e) {
    var pos = findPos(this);
    var x = e.pageX - pos.x;
    var y = e.pageY - pos.y;
    var coord = "x=" + x + ", y=" + y;
    var c = this.getContext('2d');
    var p = c.getImageData(x, y, 1, 1).data; 
    var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
    $('#status').html(coord + "<br>" + hex);
});

Le code ci-dessus suppose la présence de jQuery et des fonctions utilitaires suivantes:

function findPos(obj) {
    var curleft = 0, curtop = 0;
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
        return { x: curleft, y: curtop };
    }
    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);
}

Voyez-le en action sur JSFIDDLE:

131
Wayne Burkett

Je sais que c'est une vieille question, mais voici une alternative. Je stockais ces données d'image dans un tableau, puis lors d'un événement de déplacement de la souris sur le canevas:

var index = (Math.floor(y) * canvasWidth + Math.floor(x)) * 4
var r = data[index]
var g = data[index + 1]
var b = data[index + 2]
var a = data[index + 3]

Beaucoup plus facile que d'obtenir l'image imageData à chaque fois.

7
Caio Vertematti

En fusionnant diverses références trouvées ici dans StackOverflow (y compris l'article ci-dessus) et dans d'autres sites, je l'ai fait à l'aide de javascript et de 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>

Ceci est ma solution complète. Ici, je n’ai utilisé que canvas et une image, mais si vous devez utiliser <map> sur l'image, c'est possible aussi.

5
ebragaparah

appeler getImageData à chaque fois ralentirait le processus ... pour accélérer les choses, je vous recommande de stocker les données d'image pour pouvoir obtenir la valeur pix facilement et rapidement.

// keep it global
let imgData = false;  // initially no image data we have

// create some function block 
if(imgData === false){   
  // fetch once canvas data     
  var ctx = canvas.getContext("2d");
  imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
}
    // Prepare your X Y coordinates which you will be fetching from your mouse loc
    let x = 100;   // 
    let y = 100;
    // locate index of current pixel
    let index = (y * imgData.width + x) * 4;

        let red = imgData.data[index];
        let green = imgData.data[index+1];
        let blue = imgData.data[index+2];
        let alpha = imgData.data[index+3];
   // Output
   console.log('pix x ' + x +' y '+y+ ' index '+index +' COLOR '+red+','+green+','+blue+','+alpha);
3
user889030

Réponse rapide

context.getImageData(x, y, 1, 1).data; renvoie un tableau rgba. par exemple. [50, 50, 50, 255]


Voici une version de la fonction rgbToHex de @ lwburk qui prend le tableau rgba en argument.

function rgbToHex(rgb){
  return '#' + ((rgb[0] << 16) | (rgb[1] << 8) | rgb[2]).toString(16);
};
3
slamborne

Vous pouvez essayer color-sampler . C'est un moyen facile de choisir la couleur dans une toile. Voir démo .

2
emn178

@Wayne Burkett's réponse est bon. Si vous souhaitez également extraire la valeur alpha pour obtenir une couleur rgba, nous pouvons procéder comme suit:

var r = p[0], g = p[1], b = p[2], a = p[3] / 255;
var rgba = "rgb(" + r + "," + g + "," + b + "," + a + ")";

J'ai divisé la valeur alpha par 255 car l'objet ImageData le stockait sous forme d'entier compris entre 0 et 255, mais la plupart des applications (par exemple, CanvasRenderingContext2D.fillRect()) exigent que les couleurs soient au format CSS valide, où la valeur alpha est entre 0 et 1.

(Rappelez-vous également que si vous extrayez une couleur transparente puis que vous la redressez sur la toile, elle superposera la couleur précédente. Ainsi, si vous dessiniez la couleur rgba(0,0,0,0.1) au même endroit 10 fois, être noir.)

0
Galen Long