getImageData всегда возвращает 0 - PullRequest
8 голосов
/ 17 апреля 2011

Я пытался создать скрипт, который сравнивал бы два изображения в HTML5 и Javascript.Но по какой-то странной причине всегда возвращается, что изображения абсолютно одинаковы.

И, глядя на то, в чем может быть проблема, я обнаружил, что каждое значение данных каждого пикселя возвращалось по какой-то странной причине,"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 + "%";
}

Ответы [ 2 ]

6 голосов
/ 17 апреля 2011

Вы не ждете, пока ваши изображения будут загружены и прорисованы, прежде чем выполнять сравнение.Попробуйте это:

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.

1 голос
/ 17 апреля 2011

Я подозреваю, что проблема в том, что ваши данные изображения, вероятно, не готовы в тот момент, когда вы пытаетесь использовать их для холста. Если вы отложите этот код до обработчиков загрузки, это (вероятно) поможет:

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 + "%";
}

Все, что я сделал, это добавил функцию-оболочку вокруг вашего кода. Эта функция проверяет переменную подсчета изображений, которую я добавил, и только когда она равна нулю (т. Е. Только после загрузки обоих изображений), она выполнит свою работу.

(Это может быть суеверие, но я всегда назначаю обработчик "onload" до Я устанавливаю атрибут "src". У меня есть идея, что, возможно, только в прошлом браузеры могли не запускаться обработчик, если изображение уже находится в кэше.)

Теперь еще одна вещь: вам, вероятно, нужно просто получить данные изображения один раз, а затем перебрать возвращенные данные. Вызов getImageData () для каждого отдельного пикселя будет большой работой для браузера.

...