Зависит ли метод canvas getImageData от машины / браузера?
Клиенту нужна помощь с программой, которая извлекает доминирующий цвет изображения продукта.
Я смог быстро реализовать это в Javascript; Приведенный ниже алгоритм только отбирает центральный квадрат сетки 3х3 на изображении для быстрой оценки цвета футболки на изображении.
var image = new Image();
image.onload = function() {
try {
// get dominant color by sampling the central square of a 3x3 grid on image
var dominantColor = getDominantColor();
// output color
$("#output").html(dominantColor);
}
catch(e) {
$("#output").html(e);
}
};
image.src = "sample_image.jpg";
function getDominantColor() {
// Copy image to canvas
var canvas = $("<canvas/>")[0];
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
// get pixels from the central square of a 3x3 grid
var imageData = canvas.getContext("2d").getImageData(canvas.width/3, canvas.height/3, canvas.width/3, canvas.height/3).data;
var colorOccurrences = {};
var dominantColor = "";
var dominantColorOccurrence = 0;
for(var i = 0; i < imageData.length; i += 4) {
var red = imageData[i];
var green = imageData[i+1];
var blue = imageData[i+2];
//var alpha = imageData[i+3]; // not required for this task
var color = RGBtoHEX({"red": red, "green": green, "blue": blue});
if(colorOccurrences[color] == undefined) {
colorOccurrences[color] = 1;
}
else {
colorOccurrences[color] ++;
if(colorOccurrences[color] > dominantColorOccurrence) {
dominantColorOccurrence = colorOccurrences[color];
dominantColor = color;
}
}
}
return dominantColor;
}
function RGBtoHEX(rgb) {
var hexChars = "0123456789ABCDEF";
return "#"
+ (hexChars[~~(rgb.red/16)] + hexChars[rgb.red%16])
+ (hexChars[~~(rgb.green/16)] + hexChars[rgb.green%16])
+ (hexChars[~~(rgb.blue/16)] + hexChars[rgb.blue%16]);
}
Это изображение (предварительный просмотр ниже).
Тем не менее, результаты, когда это изображение обрабатывается в коде выше, различаются для разных машин / браузеров: #FF635E
это то, что я вижу на своей машине под управлением Windows7 и Firefox 32. Мой клиент под управлением Mac получает результат #FF474B
на сафари и #FF474C
на Firefox 33.
Хотя результаты близки, почему они в идеале не совпадают? Есть ли getImageData
на самом деле меняются в зависимости от локальной настройки, или данные JPG по-разному интерпретируются на разных машинах?
Редактировать: Это изображение не является одноразовым. Такие цветовые вариации были замечены по всему диапазону изображения, которое клиент запросил обработать. Мой клиент и я получили разные результаты для одного и того же набора изображений.
1 ответ
Да. Этот факт эксплуатируется путем снятия отпечатков на холсте:
Один и тот же элемент HTML5 Canvas может создавать исключительные пиксели в разных веб-браузерах в зависимости от системы, в которой он был выполнен.
Это происходит по нескольким причинам: на уровне формата изображения - в веб-браузерах используются разные механизмы обработки изображений, параметры экспорта, уровень сжатия, конечные изображения могут получать разные хэши, даже если они являются идеальными для пикселей; на уровне растрового изображения - операционные системы используют различные алгоритмы и настройки для сглаживания и субпиксельного рендеринга. Мы не знаем всех причин, но мы уже собрали более тысячи уникальных подписей.