web-dev-qa-db-ja.com

JavaScriptで2つの画像を比較する

2つの画像がJavaScriptで同じかどうかを確認しようとしています(たとえsrcのURLが異なっていても)。

私の具体的な使用例は、chrome拡張機能の中にあります(ただし、これはchrome拡張機能であるため、質問の要素にはなりません)。 img srcを'chrome://favicon/'+urlに設定してChromeの内部データベースに保存されているファビコンpngです。ここで、URLはWebサイトの実際のURLです。ただし、ここですべての一意のファビコンを検索します。内部データベースへの異なるURL、JavaScriptで画像を比較する簡単な方法はありますか?

ありがとう

30
JMH

いいえ、特に簡単な方法はありません。 JavaScriptは、画像処理などのバイナリデータを直接操作するなど、低レベルの操作を処理するために作成されていません。

<canvas>要素を使用して各画像をbase64エンコードする を実行し、結果の base64 文字列を比較できますが、これは画像が同一。

getBase64Image関数(私がリンクした回答で定義)を使用して2つのイメージを比較するには、次のようにします。

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

resemble.js と呼ばれるこのJavaScriptライブラリに興味があると思います。

画像を分析し、HTML5キャンバスおよびJavaScriptと比較します。

Resemble.js は、ブラウザーでの画像分析および比較の要件に使用できます。ただし、これは https://github.com/Huddle/PhantomCSS を使用した視覚回帰ライブラリPhantomCSSで使用するために設計および構築されています。 PhantomCSSは、アンチエイリアスを無視できる必要があります。これを行うと、異なるマシンから取得したスクリーンショットに違いが生じるためです。

Resemble.jsは HTML5ファイルAPI を使用して画像データを解析し、キャンバスで画像の差分をレンダリングします。

13
Igor Milla

軽量ライブラリ RembrandtJS をリリースしました。これはまさにそれを実行し、HTML5 Canvas2D APIを使用するブラウザーと、ドロップインNode.JS置換node-canvasを介したサーバーの両方で機能します。画像ソースとしてblobとurlの両方を受け入れるので、これを簡単に行うことができます。

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

ご覧のとおり、レンブラントでは、ドメインに色やピクセルの違いに関してある程度の余裕が必要な場合に、しきい値を導入することもできます。ブラウザーとサーバー(ノード)の両方で機能するため、テストスイートに簡単に統合できます。

7
Jan Bussieck

多分このツールが役に立ちます: https://github.com/HumbleSoftware/js-imagediff/

5
vitopn