web-dev-qa-db-fra.com

Comment obtenir la couleur des coordonnées x, y d'un pixel à partir d'une image?

Est-il possible de vérifier si un point (x, y) sélectionné d'une image PNG est transparent?

112
Danny Fox

En vous basant sur la réponse de Jeff, votre première étape serait de créer une représentation en toile de votre PNG. Ce qui suit crée un canevas hors écran ayant la même largeur et la même hauteur que votre image et sur lequel l’image est dessinée.

var img = document.getElementById('my-image');
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);

Après cela, lorsqu'un utilisateur clique, utilisez event.offsetX et event.offsetY pour obtenir la position. Ceci peut ensuite être utilisé pour acquérir le pixel:

var pixelData = canvas.getContext('2d').getImageData(event.offsetX, event.offsetY, 1, 1).data;

Comme vous ne saisissez qu'un pixel, pixelData est un tableau à quatre entrées contenant les valeurs R, V, B et A du pixel. Pour alpha, rien de moins que 255 représente un certain niveau de transparence, 0 étant totalement transparent.

Voici un exemple de jsFiddle: http://jsfiddle.net/thirtydot/9SEMf/869/ J'ai utilisé jQuery pour plus de commodité, mais cela n’est nullement requis.

Remarque: getImageData relève de la règle de même origine du navigateur afin d'éviter les fuites de données. Cette technique échouera si vous corrigez le canevas avec une image d'un autre domaine ou (je crois, mais certains navigateurs l'ont peut-être résolu) SVG depuis n'importe quel domaine. Cela protège contre les cas dans lesquels un site fournit une ressource d'image personnalisée à un utilisateur connecté et qu'un attaquant veut lire l'image pour obtenir des informations. Vous pouvez résoudre le problème en servant l'image à partir du même serveur ou en implémentant partage de ressources entre origines croisées .

184
Brian Nickel

La toile serait un excellent moyen de le faire, comme @pst l’a dit plus haut. Découvrez cette réponse pour un bon exemple:

getPixel à partir de HTML Canvas?

Un code qui vous servirait spécifiquement aussi:

var imgd = context.getImageData(x, y, width, height);
var pix = imgd.data;

for (var i = 0, n = pix.length; i < n; i += 4) {
  console.log pix[i+3]
}

Cela ira ligne par ligne, vous devez donc convertir cela en un x, y et convertir la boucle for en contrôle direct ou exécuter un conditionnel à l'intérieur.

En relisant votre question, il semble que vous souhaitiez pouvoir obtenir le point sur lequel la personne clique. Cela peut être fait assez facilement avec l'événement click de jquery. Il suffit de lancer le code ci-dessus dans un gestionnaire de clic en tant que tel:

$('el').click(function(e){
   console.log(e.clientX, e.clientY)
}

Ceux-ci devraient saisir vos valeurs x et y.

17
Jeff Escalante

Avec: i << 2

const data = context.getImageData(x, y, width, height).data;
const pixels = [];

for (let i = 0, dx = 0; dx < data.length; i++, dx = i << 2) {
    if (data[dx+3] <= 8)
        console.log("transparent x= " + i);
}
1
A-312

Les deux réponses précédentes montrent comment utiliser Canvas et ImageData. Je voudrais proposer une réponse avec un exemple pouvant être exécuté et utilisant un cadre de traitement d'image, de sorte que vous n'avez pas besoin de gérer les données de pixels manuellement.

MarvinJ fournit la méthode image.getAlphaComponent (x, y) qui renvoie simplement la valeur de transparence du pixel en x, y coordonner. Si cette valeur est 0, le pixel est totalement transparent, les valeurs comprises entre 1 et 254 sont des niveaux de transparence, enfin 255 est opaque.

Pour démontrer, j'ai utilisé l'image ci-dessous (300x300) avec un fond transparent et deux pixels aux coordonnées (0,0) et (150,150) .

enter image description here

Sortie de la console:

(0,0): TRANSPARENT
(150,150): NOT_TRANSPARENT

image = new MarvinImage();
image.load("https://i.imgur.com/eLZVbQG.png", imageLoaded);

function imageLoaded(){
  console.log("(0,0): "+(image.getAlphaComponent(0,0) > 0 ? "NOT_TRANSPARENT" : "TRANSPARENT"));
  console.log("(150,150): "+(image.getAlphaComponent(150,150) > 0 ? "NOT_TRANSPARENT" : "TRANSPARENT"));
}
<script src="https://www.marvinj.org/releases/marvinj-0.7.js"></script>