В любом проекте человеческий фактор никто не отменял, и если пользователи самостоятельно грузят картинки на сайт – появления дубликатов не избежать. Когда доходит до тысяч файлов, глазами всего не пересмотреть, а повторяющиеся картинки мало того что никому не нужны, так еще и занимают место, тратят ресурс и в конце концов тормозят работу.
Потому рано или поздно встает вопрос автоматизации процесса поиска повторов, и тут мы рассмотрим основные, а так же попробуем в деле.
Сравнение файлов через создание hash
Одним из способов определения дубликатов является сравнение файлов путем генерации хеш-значения из содержимого заданного файла.
Простой пример вычисления хеша изображения:
<?php imagecreatefrompng('image.png'); echo hash_file('md5', 'image.png'); ?>
Результат выглядит примерно так: bff8b4bc8b5c1c1d5b3211dfb21d1e76
Если хеши двух изображений совпадают – изображения одинаковые.
ImageMagick
Функция обработки изображений Imagick::compareImages возвращает массив, который содержит восстановленное изображение и разницу между изображениями.
Пример использования при сравненни двух изображений:
<?php header("Content-Type: image/png"); $image1 = new imagick("image1.png"); $image2 = new imagick("image2.png"); $result = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR); $result[0]->setImageFormat("png"); echo $result[0]; ?>
PHP библиотеки
Для быстрого поиска дубликатов необходимо установить библиотеки gd2 и libpuzzle.
Установка gd2 и рестарт сервера apache:
sudo apt-get install php5-gd && sudo service apache2 restart
Установка libpuzzle:
sudo apt-get install libpuzzle-php
Libpuzzle создана для быстрого поиска визуального сходства изображений (GIF, PNG, JPG). Библиотека будет работать даже если изображения были слегка изменены (ресайз, сжатие, изменения цвета). Libpuzzle довольно проста в использовании:
Вычисление подписи для двух ихображений:
$cvec1 = puzzle_fill_cvec_from_file('img1.jpg'); $cvec2 = puzzle_fill_cvec_from_file('img2.jpg');
Вычисление расстояния между подписями:
$d = puzzle_vector_normalized_distance($cvec1, $cvec2);
Проверка изображений на схожесть:
if ($d < PUZZLE_CVEC_SIMILARITY_LOWER_THRESHOLD) { echo "Pictures are looking similar\n"; } else { echo "Pictures are different, distance=$d\n"; }
Сжатие подписей для хранения в базе данных:
$compress_cvec1 = puzzle_compress_cvec($cvec1); $compress_cvec2 = puzzle_compress_cvec($cvec2);
pHash
Вот и добрались до самого точного способа нахождения дубликатов — сравнение файлов через перцептивный хеш. Проверка на схожесть проводится путем подсчета количества отличающихся позиций между двумя хешами, это расстояние Хэмминга. Чем расстояние меньше — тем больше совпадение. Отличается от первого способа тем, что указывает не только на одинаковость/неодинаковость, но и на степень различия.
Этот метод рассчитан на поиск частичных или полных дубликатов, но также найдет незначительно отредактированные картинки – с измененной яркостью, цветовой гаммой и т.д. Подробнее об этом принципе можно прочитать в неплохом переводе.
Попробовать на деле можно через /инструмент/. Загрузка изображений через интерфейс и на выдаче результаты перцептивных хешей и показатель «одинаковости».
Мы сравнили бла-бла…
ссылка на оригинал статьи http://habrahabr.ru/post/259543/
Добавить комментарий