10

HTML5 と Javascript で 2 つの画像を比較するスクリプトを作成しようとしています。しかし、何らかの奇妙な理由で、画像が完全に同じであることが常に返されます。

そして、何が問題なのかを調べたところ、すべてのピクセルのすべてのデータ値が何らかの奇妙な理由で「0」を返していることがわかりました。

それで、私が間違ったことについて何か考えはありますか?:)

なんだかとてもシンプルな気がしますが、canvas 要素について知ったばかりなので、そうです。

これは私のコードです:

function compareImg() {
    var c1 = document.getElementById("c");
    var ctx1 = c1.getContext("2d");
    var c2 = document.getElementById("c2");
    var ctx2 = c2.getContext("2d");

    var match = 0;

    var img1 = new Image();
    img1.src = "cat.jpg";
    img1.onload = function() {
        ctx1.drawImage(img1, 0, 0);
    }
    var img2 = new Image();
    img2.src = "bird.jpg";
    img2.onload = function() {
        ctx2.drawImage(img2, 0, 0);
    }


    for(var x = 0; x<c1.width; x++) {  // For each x value
        for(var y = 0; y<c1.height; y++) { // For each y value
            var data1 = ctx1.getImageData(x, y, 1, 1);
            var data2 = ctx2.getImageData(x, y, 1, 1);
            if (data1.data[0] == data2.data[0] && data1.data[1] == data2.data[1] && data1.data[2] == data2.data[2]) {
                match++;
            }
        }
    }
    var pixels = c1.width*c1.height;
    match = match/pixels*100;
    document.getElementById("match").innerHTML = match + "%";
}
4

2 に答える 2

6

比較を実行する前に、画像が読み込まれて描画されるまで待つ必要はありません。これを試して:

var img = new Image;
img.onload = function(){
  ctx1.drawImage(img,0,0);
  var img = new Image;
  img.onload = function(){
    ctx2.drawImage(img,0,0);
    // diff them here
  };
  img.src = 'cat.jpg';
};
img.src = 'cat.jpg';

上に示したように、常にのに設定する必要がありますsrc onload

于 2011-04-17T16:11:25.883 に答える
1

問題は、キャンバスに使用しようとした時点で画像データの準備ができていない可能性があることだと思います。そのコードを onload ハンドラーに任せると、(おそらく) 役立ちます。

var img1 = new Image(), count = 2;
img1.src = "cat.jpg";
img1.onload = function() {
    ctx1.drawImage(img1, 0, 0);
    checkReadiness();
}
var img2 = new Image();
img2.src = "bird.jpg";
img2.onload = function() {
    ctx2.drawImage(img2, 0, 0);
    checkReadiness();
}

function checkReadiness() {
  if (--count !== 0) return;

  for(var x = 0; x<c1.width; x++) {  // For each x value
    for(var y = 0; y<c1.height; y++) { // For each y value
        var data1 = ctx1.getImageData(x, y, 1, 1);
        var data2 = ctx2.getImageData(x, y, 1, 1);
        if (data1.data[0] == data2.data[0] && data1.data[1] == data2.data[1] && data1.data[2] == data2.data[2]) {
            match++;
        }
    }
  }
  var pixels = c1.width*c1.height;
  match = match/pixels*100;
  document.getElementById("match").innerHTML = match + "%";
}

私がしたことは、コードに関数ラッパーを追加することだけでした。この関数は、私が追加した画像カウント変数をチェックし、値がゼロの場合 (つまり、両方の画像が読み込まれた後) にのみ機能します。

(これは迷信かもしれませんが、私は常に"src" 属性を設定するに"onload" ハンドラーを割り当てます。私は、画像が既にキャッシュ。)

もう 1 つ: おそらく、画像データを 1 回取得してから、返されたデータを反復処理する必要があります。1 ピクセルごとに「getImageData()」を呼び出すことは、ブラウザにとって大変な作業になります。

于 2011-04-17T16:09:56.960 に答える