web-dev-qa-db-ja.com

ファイルが有効な画像ファイルであるかどうかを確認する方法は?

現在、PILを使用しています。

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

ただし、ほとんどの場合はこれで十分ですが、xcf、svg、psdなどの一部の画像ファイルは検出されていません。 PsdファイルはOverflowError例外をスローします。

何らかの方法でそれらを含めることはできますか?

85
Sujoy

多くの場合、最初の数文字はさまざまなファイル形式のマジックナンバーになります。上記の例外チェックに加えて、これをチェックできます。

10
Brian R. Bondy

組み込みの imghdr モジュールが見つかりました。 python documentation:

Imghdrモジュールは、ファイルまたはバイトストリームに含まれる画像のタイプを決定します。

これがどのように機能するかです:

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

モジュールを使用すると、同様の機能を再実装するよりもはるかに優れています

169
Nadia Alramli

ブライアンが提案していることに加えて、PILの verify メソッドを使用して、ファイルが壊れているかどうかを確認できます。

im.verify()

実際に画像データをデコードせずに、ファイルが壊れているかどうかを判断しようとします。この方法で問題が見つかった場合、適切な例外が発生します。このメソッドは、新しく開いた画像でのみ機能します。イメージがすでにロードされている場合、結果は未定義です。また、このメソッドを使用した後にイメージをロードする必要がある場合は、イメージファイルを再度開く必要があります。属性

41
Nadia Alramli

Linuxでは、python-magic( http://pypi.python.org/pypi/python-magic/0.1 )を使用できます。これは、libmagicを使用してファイル形式を識別します。

知る限りでは、libmagicはファイルを調べて、ビットマップのサイズ、フォーマットバージョンなど、フォーマットについてだけでなく、それ以上のことを伝えようとします。したがって、これは「妥当性」の表面的なテストとみなされます。

「有効」の他の定義については、独自のテストを作成する必要があります。

3
fmarc

Python libmagicへのバインディング、 python-magic を使用してから、MIMEタイプを確認できます。画像のタイプを判別できる必要があります。

3
Kamil Kisiel

まあ、私はpsdの内部については知りませんが、確かに、svgはそれ自体がイメージファイルではないことを知っています-それはxmlに基づいているので、本質的に、プレーンテキストファイル。

2
shylent

更新

また、Python script ここではGitHubで

また、破損したファイル(jpg)は頻繁に「破損した」画像ではないことも確認しました。つまり、破損した画像ファイルは正当な画像ファイルのままである場合があり、元の画像は失われたり変更されたりしますが、エラーなしで読み込むことができます。ただし、ファイルの切り捨ては常にエラーを引き起こします。

更新の終了

PythonPillow(PIL)モジュールをほとんどの画像形式で使用して、ファイルが有効で完全な画像ファイルであるかどうかを確認できます。

壊れた画像も検出することを目的とする場合、@ Nadia Alramliはim.verify()メソッドを正しく提案しますが、このは考えられるすべての画像欠陥を検出しません、たとえば、im.verifyは、切り捨てられた画像を検出しません(ほとんどの視聴者が灰色の領域で読み込むことが多い)。

Pillowはこれらのタイプの欠陥も検出できますが、画像操作または画像デコード/再コードを適用するか、チェックをトリガーする必要があります。最後に、このコードを使用することをお勧めします。

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倍高速であると考えてください(フリップは安価な変換の1つだと思います)。このコードを使用して、標準ピローでは約10メガバイト/秒、ピローSIMDモジュール(最新の2.5Ghz x86_64 CPU)では40メガバイト/秒で画像セットを検証します。

その他の形式psdxcf、..を使用できますImagemagickラッパーワンド、コードは次のとおりです。

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

しかし、私の実験から、ワンドは切り捨てられた画像を検出しないので、プロンプトを表示せずにグレーの領域として不足している部分をロードすると思います。

Imagemagickに外部コマンドがあるidentifythatcould仕事をしますが、私はその機能をプログラムで呼び出す方法を見つけていませんし、このルートをテストしていません。

filesizeがゼロ(または非常に小さい)でないことを確認し、非常にcheapアイデア:

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

PILイメージチェックに加えて、次のようなファイル名拡張子チェックも追加できます。

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

これは、ファイル名に有効な画像拡張子があるかどうかを確認するだけで、実際に画像を開いて有効な画像かどうかを確認するわけではないことに注意してください。そのため、PIL他の答え。

1
tsveti_iko

ファイル拡張子をチェックしても問題ありませんか、データ自体が画像ファイルを表していることを確認しようとしていますか?

ファイル拡張子を確認できる場合、正規表現または単純な比較で要件を満たすことができます。

1
doomspork