Как получить "хеш"/сравнить изображение?

Ссылка скопирована
1 ответ

Добрый день. Задача такова: уменьшить количество дублирующихся изображений на сервере (wordpress, если это важно).
Есть новостной сайт, иногда у новостей могут проскакивать одни и те же изображения, которые каждый раз были загружены повторно, хотя они 1в1 (или около того) похожи. Я хочу при загрузке изображений, записывать некий хеш в БД, и если я буду загружать подобное изображение снова, чтобы система мне сообщала, что такое изображение уже существует. На счет получения хеша изображения, может быть эта задача и не сложная, но как быть с такими дублями, если размер/пиксели и прочие мелочи могут не значительно отличаться?
Можете дать направление, как можно сравнивать изображения на сервере, чтобы уменьшить количество дублей?

Дополнительно:

Justa Gain, с хешем файлов, в принципе, проблем и не будет, хотя действительно, надо сначала тест провести, а там глядишь, уже большое количество изображений может отсечься

Как получить "хеш"/сравнить изображение?

Гуглить perceptual hash.

Одна из реализаций

https://github.com/jenssegers/imagehash

  • На первый взгляд прям очень хорошая реализация, изучу
  • Пока что это решение кажется лучшим, по нескольким тестах показатели довольно хорошие

Ответы:

https://php.net/md5_file

  • Только для полностью идентичных файлов, отличие в одном пикселе или даже в мета-данных даст разный хеш.

Простое сравнение изображений с помощью php

  • Кстати, кажется, я подобную реализацию видел для питона. Изучу, спасибо

Для ведения новостей прежде всего нужно определить порядок, как создавать каталоги для хранения сопутствующего контента для людей, кто ведет их. Если плагин галереи не берет на себя обязанность автоматически создавать каталоги под свои нужды и не скрывает это от контент-менеджера, то контент-менеджер (человек) тупо складывает картинки в один каталог.
На моей практике я делаю так.
Под новости создаю каталог news, в каталоге на каждый год создаю каталог года - 2023.
Внутри каталога года создается каталог конкретной новости, который создается менеджером для новости, если требуется положить дополнительный контент. Обычно, имя у него такое: YYYY_MM_DD_NN, где YYYY - год, MM - месяц, DD - день, NN - порядковое число новости в один день.
Для повторяющегося контента можно задать каталог по умолчанию в news, например default, и складывать туда часто используемые изображения, заглушки и т.д.
И самое, главное, чтобы эту практику поддерживали менеджеры, тогда проблем с дублированием не будет, и не будет бардака в новостях.

  • Все по стандарту в ВордПресс. Там по-моему подкаталог год/месяц/имя-файла
    Галереи отдельной нет, тоже стандартный медиа-зазгрузчик.
    Из банального могу реализовать такое:
    - проверка по имени файла, т.к. дубли не редко одинаково называются, а потом вп им просто приписывает цифру, чтобы имя было уникальное
    - получения хеша содержимого, но изменение в один байт уже сделает хеши разными

    Вот и ищу что-то более универсальное

Как получить "хеш"/сравнить изображение?

На хабре есть несколько статей, и с самописными решениями и с готовыми инструментами.
https://www.google.com/search?q=habr+%D1%81%D1%80%...

Чтобы не изобретать кривые велосипеды https://wordpress.org/plugins/media-deduper/

  • Он работает на основе md5_file, который предложил Ипатьев. Частично это тоже по теме, но хочется несколько шире функционал. Я сейчас изучаю ответ Дмитрий , и на данный момент, это кажется лучшим решение
  • maksam07,

    Он работает на основе md5_file,

    Он готовый. Установил и сразу решил свою задачу.
    Но если тебе интересно потратить кусок жизни для написания своего (такого же, но хуже) плагина - я не против.

  • Refguser, толку от того, что плагин работает, если он не выполняет нужную мне задачу? Любой лишний байт вставил и плагин уже не видит дубликат.
    И почему "хуже"?
  • maksam07, поставь посмотри, попробуй загрузить копию с изменением в "1 байт".
  • Refguser, посмотрел. Не видит он дубля при изменении даже 1 байта. Даже при таком же кол-ве байтов, но другом содержимом.
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Юрий Linux Ответ

Для одинаковых файлов достаточно обычного хеша файла: md5_file() или sha1_file(). Но если изображение чуть пережато, изменён размер, EXIF или качество JPEG, файловый хеш будет другим. Для “почти одинаковых” картинок нужен perceptual hash: dHash, pHash или aHash.

Практическая схема для WordPress:

  1. при загрузке attachment считать sha1_file для точных дублей;
  2. дополнительно считать perceptual hash для похожих изображений;
  3. сохранять оба значения в post meta;
  4. при новой загрузке сравнивать сначала точный hash, потом perceptual hash по расстоянию Хэмминга.

Точный hash:

add_action('add_attachment', function ($attachment_id) {
    $file = get_attached_file($attachment_id);
 
    if (!$file || !file_exists($file)) {
        return;
    }
 
    update_post_meta($attachment_id, '_file_sha1', sha1_file($file));
});

add_action('add_attachment', function ($attachment_id) { $file = get_attached_file($attachment_id); if (!$file || !file_exists($file)) { return; } update_post_meta($attachment_id, '_file_sha1', sha1_file($file)); });

Дальше можно искать точные дубли:

$same = get_posts([
    'post_type'      => 'attachment',
    'post_status'    => 'inherit',
    'posts_per_page' => 10,
    'meta_key'       => '_file_sha1',
    'meta_value'     => sha1_file($file),
    'fields'         => 'ids',
]);

$same = get_posts([ 'post_type' => 'attachment', 'post_status' => 'inherit', 'posts_per_page' => 10, 'meta_key' => '_file_sha1', 'meta_value' => sha1_file($file), 'fields' => 'ids', ]);

Для похожих изображений лучше использовать готовую библиотеку под PHP, например реализацию pHash/dHash через GD или Imagick. Самодельная логика возможна, но её нужно тестировать на ваших картинках: для новостного сайта порог похожести может давать ложные совпадения на однотипных фото.

Важно: не удаляйте дубли автоматически. Сначала показывайте редактору предупреждение “похоже на уже загруженное изображение” со ссылкой на найденный attachment. Иначе можно случайно удалить изображение, которое уже используется в старой статье.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно