it-swarm.com.de

Wie prüfe ich, ob eine Datei eine gültige Bilddatei ist?

Ich verwende derzeit PIL.

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

Während dies die meisten Fälle ausreichend abdeckt, werden einige Bilddateien wie xcf, svg und psd nicht erkannt. Psd-Dateien lösen eine OverflowError-Ausnahme aus.

Kann ich sie auch irgendwie einbinden?

75
Sujoy

Oft sind die ersten paar Zeichen eine magische Zahl für verschiedene Dateiformate. Sie können dies zusätzlich zu Ihrer oben genannten Ausnahmekontrolle prüfen. 

10
Brian R. Bondy

Ich habe gerade das eingebaute imghdr Modul gefunden. Aus der Python-Dokumentation:

Das imghdr-Modul bestimmt den Typ eines Bildes, das in einer Datei oder einem Byte enthalten ist Strom.

So funktioniert es:

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

Die Verwendung eines Moduls ist viel besser, als eine ähnliche Funktionalität erneut zu implementieren

158
Nadia Alramli

Zusätzlich zu dem, was Brian vorschlägt, können Sie die PIL-Methode verify verwenden, um zu prüfen, ob die Datei beschädigt ist.

im.verify ()

Versucht festzustellen, ob die Datei .__ ist. kaputt, ohne die .__ tatsächlich zu decodieren. Bilddaten. Wenn diese Methode eine .__ findet. Probleme, wirft dies geeignet Ausnahmen. Diese Methode funktioniert nur für ein neu geöffnetes Bild; wenn das Bild hat bereits geladen wurde, lautet das Ergebnis nicht definiert. Auch wenn Sie .__ laden müssen. das Bild nach der Verwendung dieser Methode, Sie muss die Bilddatei erneut öffnen. Attribute

40
Nadia Alramli

Sie können die Python-Bindungen für libmagic, python-magic verwenden und dann die MIME-Typen überprüfen. Dies sagt Ihnen nicht, ob die Dateien beschädigt oder intakt sind, aber es sollte in der Lage sein zu bestimmen, um welche Art von Image es sich handelt.

3
Kamil Kisiel

Nun, ich weiß nicht über die Innenseiten von psd Bescheid, aber ich weiß natürlich, dass es sich bei svg eigentlich nicht um eine Bilddatei an sich handelt - es basiert auf xml, also im Wesentlichen eine Nur-Text-Datei.

2
shylent

Unter Linux können Sie Python-Magic ( http://pypi.python.org/pypi/python-magic/0.1 ) verwenden, das mit libmagic Dateiformate identifiziert.

AFAIK, libmagic schaut in die Datei und versucht, Ihnen mehr zu sagen als nur das Format, wie z. B. Bitmap-Dimensionen, Formatversion usw. Sie können dies als oberflächlichen Test auf "Gültigkeit" betrachten.

Für andere Definitionen von "gültig" müssen Sie möglicherweise eigene Tests schreiben.

2
fmarc

Update

Ich habe auch die folgende Lösung in meinem Python script hier auf GitHub implementiert.

Ich habe auch überprüft, dass beschädigte Dateien (jpg) häufig keine "defekten" Bilder sind, d. H. Eine beschädigte Bilddatei bleibt manchmal eine legitime Bilddatei, das Originalbild geht verloren oder wird geändert, aber Sie können es weiterhin fehlerfrei laden. Das Abschneiden von Dateien führt jedoch immer zu Fehlern.

Update beenden

Mit dem Modul Python Pillow (PIL) können Sie bei den meisten Bildformaten prüfen, ob es sich bei einer Datei um eine gültige und intakte Bilddatei handelt.

Wenn Sie auch defekte Bilder erkennen möchten, schlägt @Nadia Alramli die Methode im.verify() korrekt vor, aber diese erkennt nicht alle möglichen Bildfehler , z , im.verify erkennt keine abgeschnittenen Bilder (die von den meisten Zuschauern häufig mit einem grauen Bereich geladen werden).

Pillow kann auch diese Art von Fehlern erkennen, Sie müssen jedoch eine Bildmanipulation oder eine Bilddecodierung/-recodierung durchführen oder die Prüfung auslösen. Schließlich schlage ich vor, diesen Code zu verwenden:

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

Bei Bildmängeln löst dieser Code eine Ausnahme aus. Bitte bedenken Sie, dass im.verify etwa 100-mal schneller ist als die Bildbearbeitung (und ich denke, dass Flip eine der billigeren Transformationen ist). Mit diesem Code überprüfen Sie einen Satz von Bildern mit einer Geschwindigkeit von ca. 10 MByte/s mit Standardkissen oder 40 MByte/s mit Kissen-SIMD-Modul (moderne 2,5-GHz-x86_64-CPU).

Für die anderen Formate psd, xcf, .. können Sie Imagemagick wrapper Wand, der Code lautet wie folgt:

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

Aus meinen Experimenten geht jedoch hervor, dass Wand keine abgeschnittenen Bilder erkennt. Ich denke, es werden fehlende Teile ohne Aufforderung als grauer Bereich geladen.

Ich rede das Imagemagick hat einen externen Befehl identifizieren das könnte den Job machen, habe ich aber nicht gefunden eine Möglichkeit, diese Funktion programmgesteuert aufzurufen, und ich habe diese Route nicht getestet.

Ich schlage vor, immer eine Vorabprüfung durchzuführen, die Dateigröße nicht Null (oder sehr klein) zu sein, ist eine sehr billige Idee:

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

Zusätzlich zur Bildüberprüfung PIL können Sie die Prüfung der Dateinamenerweiterung wie folgt hinzufügen:

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

Beachten Sie, dass hiermit nur überprüft wird, ob der Dateiname eine gültige Bilderweiterung hat. Das Bild wird jedoch nicht geöffnet, um festzustellen, ob es sich um ein gültiges Bild handelt. Daher müssen Sie zusätzlich PIL oder eine der in der vorgeschlagenen Bibliotheken verwenden Andere Antwort.

1
tsveti_iko

Wäre die Überprüfung der Dateierweiterungen akzeptabel oder versuchen Sie zu bestätigen, dass die Daten selbst eine Bilddatei darstellen?

Wenn Sie die Dateierweiterung überprüfen können, kann ein regulärer Ausdruck oder ein einfacher Vergleich die Anforderung erfüllen.

1
doomspork