Как проверить, является ли файл допустимым файлом изображения? - PullRequest
78 голосов
/ 20 мая 2009

Я сейчас использую PIL.

from PIL import Image
try:
    im=Image.open(filename)
    # do stuff
except IOError:
    # filename not an image file

Однако, хотя это в достаточной степени покрывает большинство случаев, некоторые файлы изображений, такие как, xcf, svg и psd, не обнаруживаются. Psd-файлы выдают исключение OverflowError.

Могу ли я как-нибудь их включить?

Ответы [ 8 ]

166 голосов
/ 24 мая 2009

Я только что нашел встроенный модуль imghdr . Из документации по питону:

Модуль imghdr определяет тип изображения, содержащегося в файле или байте поток.

Вот как это работает:

>>> import imghdr
>>> imghdr.what('/tmp/bass')
'gif'

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

40 голосов
/ 20 мая 2009

В дополнение к тому, что предлагает Брайан, вы можете использовать метод PIL verify , чтобы проверить, не поврежден ли файл.

im.verify ()

Попытки определить, является ли файл сломан, фактически не расшифровывая данные изображения. Если этот метод находит какой-либо проблемы, это поднимает подходящие исключения. Этот метод работает только на вновь открытое изображение; если изображение имеет уже был загружен, результат не определено. Кроме того, если вам нужно загрузить изображение после использования этого метода, вы должен снова открыть файл изображения. Атрибуты

9 голосов
/ 20 мая 2009

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

3 голосов
/ 20 мая 2009

Вы можете использовать привязки Python к libmagic, python-magic и затем проверять типы пантомимы. Это не скажет вам, повреждены ли файлы или нет, но должно быть в состоянии определить, какой это тип изображения.

3 голосов
/ 20 мая 2009

В Linux вы можете использовать python-magic (http://pypi.python.org/pypi/python-magic/0.1), которая использует libmagic для определения форматов файлов.

AFAIK, libmagic просматривает файл и пытается рассказать вам больше о нем, чем просто о формате, например, о растровых измерениях, версии формата и т. Д. Таким образом, вы можете увидеть это как поверхностный тест на «достоверность».

Для других определений «действительных» вам, возможно, придется написать свои собственные тесты.

2 голосов
/ 20 мая 2009

Ну, я не знаю о внутренностях PSD, но я, конечно, знаю, что, по сути, SVG не является файлом изображения как таковым, - он основан на XML, так что по сути, простой текстовый файл.

1 голос
/ 25 ноября 2018

Обновление

Я также реализовал следующее решение в своем скрипте Python здесь, на GitHub .

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

Окончание обновления

Вы можете использовать модуль Python Pillow (PIL), с большинством форматов изображений, чтобы проверить, является ли файл действительным и неповрежденным файлом изображения.

В случае, если вы стремитесь обнаружить также поврежденные изображения, @Nadia Alramli правильно предлагает метод im.verify(), но этот не обнаруживает все возможные дефекты изображения , например, im.verify не обнаруживает усеченные изображения (которые большинство зрителей часто загружают с серой областью).

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

try:
  im = Image.load(filename)
  im.verify() #I perform also verify, don't know if he sees other types o defects
  im.close() #reload is necessary in my case
  im = Image.load(filename) 
  im.transpose(PIL.Image.FLIP_LEFT_RIGHT)
  im.close()
except: 
  #manage excetions here

В случае дефектов изображения этот код вызовет исключение. Пожалуйста, учтите, что im.verify примерно в 100 раз быстрее, чем выполнение манипуляций с изображениями (и я думаю, что flip - это одно из самых дешевых преобразований). С помощью этого кода вы собираетесь проверить набор изображений со скоростью около 10 МБ / с со стандартной подушкой или 40 МБ / с с модулем Pillow-SIMD (современный процессор с частотой 2,5 ГГц x86_64).

Для других форматов psd , xcf , .. вы можете использовать Imagemagick wrapper Wand , код следующий:

im = wand.image.Image(filename=filename)
temp = im.flip;
im.close()

Но из моих экспериментов Wand не обнаруживает усеченные изображения, я думаю, что загружает недостающие части в виде серой области без запроса.

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

Я предлагаю всегда выполнять предварительную проверку, проверьте, чтобы размер файла не был нулевым (или очень маленьким), это очень дешевая идея:

statfile = os.stat(filename)
filesize = statfile.st_size
if filesize == 0:
  #manage here the 'faulty image' case
1 голос
/ 20 мая 2009

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

Если вы можете проверить расширение файла, регулярное выражение или простое сравнение могут удовлетворить требование.

...