web-dev-qa-db-fra.com

Comment vérifier si un fichier est un fichier image valide?

J'utilise actuellement PIL.

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

Cependant, bien que cela couvre suffisamment la plupart des cas, certains fichiers images tels que xcf, svg et psd ne sont pas détectés. Les fichiers psd lève une exception OverflowError.

Y a-t-il un moyen de les inclure également?

75
Sujoy

Souvent, le premier couple de caractères sera un nombre magique pour divers formats de fichiers. Vous pouvez vérifier cela en plus de votre vérification d'exception ci-dessus. 

10
Brian R. Bondy

Je viens de trouver le module intégré imghdr . De la documentation python:

Le module imghdr détermine le type d'une image contenue dans un fichier ou un octet courant.

Voilà comment cela fonctionne:

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

Utiliser un module est bien meilleur que de réimplémenter des fonctionnalités similaires

158
Nadia Alramli

En plus de ce que Brian suggère, vous pouvez utiliser la méthode verify de PIL pour vérifier si le fichier est cassé.

im.verify ()

Tente de déterminer si le fichier est cassé, sans décoder réellement le données d'image. Si cette méthode en trouve problèmes, il soulève convenable exceptions. Cette méthode ne fonctionne que sur une image nouvellement ouverte; si l'image a déjà été chargé, le résultat est indéfini. Aussi, si vous avez besoin de charger l'image après avoir utilisé cette méthode, vous doit rouvrir le fichier image. Les attributs

40
Nadia Alramli

Vous pouvez utiliser les liaisons Python à libmagic, python-magic , puis vérifier les types mime. Cela ne vous dira pas si les fichiers sont corrompus ou intacts, mais il devrait être en mesure de déterminer le type d'image dont il s'agit.

3
Kamil Kisiel

Eh bien, je ne connais pas l’intérieur de psd, mais je sais bien que, en fait, svg n’est pas un fichier image en tant que tel; fichier texte brut.

2
shylent

Sous Linux, vous pouvez utiliser python-magic ( http://pypi.python.org/pypi/python-magic/0.1 ), qui utilise libmagic pour identifier les formats de fichier.

Autant que je sache, libmagic examine le fichier et essaie de vous en dire davantage que le format, comme les dimensions bitmap, la version du format, etc. Vous pouvez donc voir cela comme un test superficiel de "validité".

Pour d'autres définitions de "valide", vous devrez peut-être écrire vos propres tests.

2
fmarc

En plus de la vérification d'image PIL, vous pouvez également ajouter une vérification d'extension de nom de fichier comme ceci:

filename.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif'))

Notez que ceci vérifie seulement si le nom du fichier a une extension d'image valide, il n'ouvre pas réellement l'image pour voir si c'est une image valide, c'est pourquoi vous devez utiliser en plus PIL ou l'une des bibliothèques suggérées dans le fichier. d'autres réponses.

1
tsveti_iko

Est-ce que la vérification des extensions de fichier serait acceptable ou essayez-vous de confirmer que les données elles-mêmes représentent un fichier image?

Si vous pouvez vérifier l'extension du fichier, une expression régulière ou une simple comparaison peut satisfaire à l'exigence.

1
doomspork

Mettre à jour

J'ai également implémenté la solution suivante dans mon script Python ici sur GitHub .

J'ai également vérifié que les fichiers endommagés (jpg) ne sont souvent pas des images "brisées", c.-à-d. Qu'un fichier image endommagé reste parfois un fichier image légitime, l'image d'origine est perdue ou modifiée, mais vous pouvez toujours le charger sans erreur. Mais la troncature de fichier cause toujours des erreurs. 

Fin de mise à jour

Vous pouvez utiliser le module Python Pillow _ (PIL), avec la plupart des formats d'image, pour vérifier si un fichier est un fichier image valide et intact.

Si vous souhaitez détecter également les images brisées, @Nadia Alramli suggère correctement la méthode im.verify(), mais ce ne détecte pas tous les défauts possibles de l'image, par exemple, im.verify ne détecte pas les images tronquées (que la plupart des téléspectateurs chargent souvent avec une zone grisée).

Pillow est également capable de détecter ce type de défaut, mais vous devez appliquer une manipulation ou un décodage/recodage d'image ou déclencher la vérification. Enfin, je suggère d'utiliser ce code:

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

En cas de défauts d’image, ce code lèvera une exception .Veuillez considérer qu’im.verify est environ 100 fois plus rapide que la manipulation d’image (et je pense que le retournement est l’une des transformations les moins chères) . code vous allez vérifier un ensemble d’images à environ 10 Mo/s avec un oreiller standard ou 40 Mo/s avec un module Pillow-SIMD (processeur 2,5 GHz x86_64 moderne).

Pour les autres formats psd, xcf, .., vous pouvez utiliser Imagemagick wrapper Wand, le code est le suivant:

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

Mais, à partir de mes expériences, Wand ne détecte pas les images tronquées, je pense que cela charge les parties manquantes comme une zone grisée sans y être invité. 

Je pense que (Imagemagick} _ a une commande externe identifier que pourrait effectuer le travail, mais je n'ai pas trouvé le moyen d'appeler cette fonction par programme et je n'ai pas testé cette route. .

Je suggère de toujours effectuer une vérification préliminaire, vérifiez le taille du fichier pour ne pas être zéro (ou très petit), est une très très {pas cher idée:

statfile = os.stat(filename)
filesize = statfile.st_size
if filesize == 0:
  #manage here the 'faulty image' case
0
Fabiano Tarlao