Как найти недействительные изображения?

Как найти недействительные изображения?

У меня есть каталог с подкаталогами. В каталогах находится множество изображений, взятых из Интернета.

Как мне перебрать все файлы и отобразить те из них, которые не являются допустимыми файлами изображений?

Он не должен основываться на расширении файла.

Я придумал такой сценарий:

find . -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' | while read FILE; do
    if ! identify "$FILE" &> /dev/null; then
         echo "$FILE"
    fi  
done

Но это не работает, поскольку выводит также и допустимые изображения.

решение1

find . -type f \
       \( -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' \) \
       -exec sh -c '! file -b --mime-type "$1" | grep -q "^image/"' sh {} \; \
       -print

Мой подход использует -execдля выполнения пользовательского теста на файлах. Для построения конвейера требуется оболочка. Отдельная оболочка запускается для каждого файла с правильным расширением, поэтому решение работает довольно плохо.

Оболочка запускает file -b --mime-type, затем grepпроверяет, начинается ли результат с image/. !в начале канала, отрицает его статус выхода, поэтому весь -execтест завершается успешно, если файл на самом деле не является изображением. Затем выводится путь.

Примечания:

  1. Пропустить -nameтесты для проверки всех файлов.
  2. Или вы можете использовать -inameвместо -name.
  3. -inameХотя POSIX не требует. Ни то, ни -bдругое не является --mime-typeопцией file.
  4. Следующий код дает немного другой результат, и он работает быстрее:

    find . -type f \
           \( -name '*.jpg' -o -name '*.jpeg' -o -name '*.gif' -o -name '*.png' \) \
           -exec file --mime-type {} + \
    | grep -v "\bimage/"
    

    нонекоторые имена файлов (например, с символами новой строки) или пути (с image/) нарушат логику.

решение2

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

Например, подпись JPG — FF D8 FF E0, что означает, что ее первые четыре байта должны быть равны FF D8 FF E0.

Все, что вам нужно, это инструмент для сопоставления этих байтов с байтами файла. Например, hexdump -n 4 -C file.jpg| awk '{print $2 $3 $4 $5}'возвращает эти байты в шестнадцатеричном формате, которые можно сравнить с желаемой сигнатурой.

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

решение3

Проверка расширения файла и магические байты могут быть легко подделаны. Смотритеhttps://unix.stackexchange.com/questions/189364/script-to-determine-if-apparent-image-files-are-real-image-files/189367#189367для вдохновения, в основном используйте imagemagick, чтобы проверить, является ли изображение действительным, но даже в этом случае его можно подделать! Так что идеального способа проверки нет.

Связанный контент