web-dev-qa-db-fra.com

Comparez deux images en JavaScript

J'essaie de déterminer si deux images sont les mêmes en javascript (même si les URL src sont différentes).

Mon cas d'utilisation spécifique se trouve dans une extension chrome (bien que ce soit une extension chrome ne tient pas vraiment compte de la question). Je peux obtenir l'image de un favicon png stocké dans la base de données interne de chrome en définissant l'img src sur: 'chrome://favicon/'+url où l'URL est l'URL réelle du site Web. Cependant, je veux maintenant trouver tous les favicons uniques. Étant donné qu'ils auront tous une URL différente vers la base de données interne, existe-t-il un moyen simple de comparer les images en javascript?

Merci

30
JMH

Non, il n'y a pas spécialement moyen facile de le faire. JavaScript n'a pas été conçu pour gérer des opérations de bas niveau telles que le travail direct avec des données binaires pour, par exemple, le traitement d'images.

Vous pouvez tilisez un <canvas> élément à base64 encoder chaque image , puis comparer les chaînes base64 résultantes, mais cela vous indiquera uniquement si les images sont identiques ou non.

Pour utiliser le getBase64Image fonction (définie dans la réponse que j'ai liée) pour comparer deux images:

var a = new Image(),
    b = new Image();
a.src = 'chrome://favicon/' + url_a;
b.src = 'chrome://favicon/' + url_b;

// might need to wait until a and b have actually loaded, ignoring this for now
var a_base64 = getBase64Image(a),
    b_base64 = getBase64Image(b);

if (a_base64 === b_base64)
{
    // they are identical
}
else
{
    // you can probably guess what this means
}
31
Matt Ball

Je pense que vous pourriez être intéressé par cette bibliothèque JavaScript appelée resemble.js qui:

Analyse et compare les images avec le canevas HTML5 et JavaScript.

Resemble.js peut être utilisé pour toute exigence d'analyse d'image et de comparaison que vous pourriez avoir dans le navigateur. Cependant, il a été conçu et construit pour être utilisé par la bibliothèque de régression visuelle propulsée https://github.com/Huddle/PhantomCSS PhantomCSS. PhantomCSS doit pouvoir ignorer l'anticrénelage, car cela entraînerait des différences entre les captures d'écran dérivées de différentes machines.

Resemble.js utilise API de fichier HTML5 pour analyser les données d'image et le canevas pour le rendu des différences d'image.

13
Igor Milla

Nous venons de publier une bibliothèque légère RembrandtJS , qui fait exactement cela et qui fonctionne à la fois dans le navigateur utilisant l'API HTML5 Canvas2D ainsi que sur le serveur via le drop-in Node.JS remplacement node-canvas. Il accepte les blobs et les URL comme sources d'images, vous pouvez donc simplement faire ceci:

const rembrandt = new Rembrandt({
  // `imageA` and `imageB` can be either Strings (file path on node.js,
  // public url on Browsers) or Buffers
  imageA: 'chrome://favicon/' + url_a,
  imageB: 'chrome://favicon/' + url_b,

  thresholdType: Rembrandt.THRESHOLD_PERCENT,

  // The maximum threshold (0...1 for THRESHOLD_PERCENT, pixel count for THRESHOLD_PIXELS
  maxThreshold: 0,

  // Maximum color delta (0...255):
  maxDelta: 0,

  // Maximum surrounding pixel offset
  maxOffset: 0,

})

// Run the comparison
rembrandt.compare()
  .then(function (result) {

    if(result.passed){
      // do what you want
    }
  })

Comme vous pouvez le voir, Rembrandt vous permet également d'introduire des valeurs de seuil, si votre domaine nécessite une certaine latitude en ce qui concerne la différence de couleur ou de pixels. Comme il fonctionne à la fois dans le navigateur et sur le serveur (nœud), il est facile à intégrer dans votre suite de tests.

7
Jan Bussieck

Peut-être que cet outil vous aidera: https://github.com/HumbleSoftware/js-imagediff/

5
vitopn