getImageData всегда возвращает 0
Я пытался сделать сценарий, который сравнивает два изображения в 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 ответа
Вы не ждете, пока ваши изображения будут загружены и прорисованы, прежде чем выполнять сравнение. Попробуй это:
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
,
Я подозреваю, что проблема в том, что ваши данные изображения, вероятно, не готовы в тот момент, когда вы пытаетесь использовать их для холста. Если вы передадите этот код обработчикам 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 + "%";
}
Все, что я сделал, это добавил функцию-обертку вокруг вашего кода. Эта функция проверяет переменную подсчета изображений, которую я добавил, и только тогда, когда она равна нулю (то есть, только после загрузки обоих изображений), она выполнит свою работу.
(Это может быть суеверием, но я всегда назначаю обработчик "onload" перед тем, как установить атрибут "src". У меня есть идея, что, возможно, только в прошлом браузеры могут не запускать обработчик, если изображение уже находится в кэш).
Теперь еще одна вещь: вам, вероятно, нужно просто получить данные изображения один раз, а затем перебрать возвращенные данные. Вызов "getImageData()" для каждого пикселя будет большой работой для браузера.