ファイルが有効な画像ファイルかどうかを確認するにはどうすればよいですか?


105

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

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

ただし、これでほとんどのケースが十分カバーされますが、xcf、svg、psdなどの一部のイメージファイルが検出されません。PsdファイルはOverflowError例外をスローします。

それらを含めることもできますか?


21
異なる言語間で重複を閉じることは特に一般的ではありません。他のPythonの質問が見つからない場合は、開いたままにしてください。投稿したい質問に到達しなかった、Python固有のソリューションが投稿される可能性があるためです。
Paolo Bergantino、

はい、まず第一に、私は:Pについて知らなかったpython libを本当に望んでいました。
Sujoy

@Sujoy、画像全体を検証することは、すでにコピーがない限り、ほぼ不可能です。なぜなら、すべてのコントロールがある限り、コンピューターは正しいカラーピクセルと1と0の文字化けセットの違いを区別できないからです。 (マジックナンバー)は正しいです。
DevinB 2009年

@devinb、同意しました。他の誰かがリファクタリングを要求するより良い何かを思い付かない限り、私はマジックナンバーを取得してそれで完了します:)
Sujoy

xcfとpsdは実際にはイメージではなく、(多くの場合)イメージが含まれているプロジェクトファイルです。おそらくsvgのケースを作成できます。
mgalgs 2014年

回答:


11

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


10
彼が本当に「有効な」画像をテストしているのであれば、それは十分ではありません。たとえば、マジックナンバーの存在は、ファイルが切り捨てられていないことを保証するものではありません。
Ben Blank

1
素晴らしいアドバイスです。今、それらの数字が何であるかを理解する必要があります。おかげで:)
Sujoy

@ben、それはまだ考えていませんでした。それは確かに良い点です
Sujoy

@ベン、ライブラリがファイルが切り捨てられたと推測する方法は?
DevinB 2009年

6
@Ben Blank:正しいですが、99%の方法で問題を解決する方が、まったく解決しないよりも優れていることがよくあります。
ブライアンR.ボンディ

205

組み込みのimghdrモジュールを見つけました。Pythonのドキュメントから:

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

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

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

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


2
はいimghdrはほとんどの画像フォーマットで機能しますが、すべてでは機能しません。svg、xcf、およびpsdファイルに関する私の元の問題に従って、それらはimghdrでも検出されません
Sujoy

2
あなたの答えは実際にはより良いです、ありがとう。言った以上誰かのように...しかし、道の99%が、多くの場合、より良い、すべて...でそれを解決していない問題を解決する
RinkyPinku

2
注意する価値:指定された画像ファイルタイプが認識されない場合にimghdr.what(path)返されます。現在認識されている画像タイプのリストrgbgifpbmpgmppmtiffrastxbmjpegbmppngwebpexrNonepath
patryk.beza

1
注意してください!有効なhdrは有効な画像を意味するものではありません(たとえば、画像のバイトがスクランブルされている可能性があります!)
Filippo Mazza '30

1
@FilippoMazzaのコメントによれば、転送中に切り取られた不良画像はこのテストに合格する可能性がありますが、PILが読み取ろうとすると壊れます。
kevinmicke

47

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

im.verify()

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


主な問題は、svg、xcf、およびpsdファイルをImage.open()で開くことができないため、im.verify()で検証する機会がないことです
Sujoy

16
PILのドキュメントがひどいです。「適切な例外」とは正確には何ですか?
Timmmm 2012

Image.verify()のPillowドキュメントへのリンクは次のとおりです。残念ながら、それは良くないことであり、何も追加せずに上記の段落を持ち上げたようです。
2ビットの錬金術師

破損したpngファイルに対して構文エラーが発生することを確認しました
Carl

「実際に画像データをデコードして」を確認する方法はありますか?
Trevor Boyd Smith

7

PIL画像チェックに加えて、次のようにファイル名拡張子チェックを追加することもできます:

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

これは、ファイル名に有効な画像拡張子があるかどうかを確認するだけであり、実際に画像を開いて有効な画像であるかどうかを確認しないことに注意してください。そのため、追加PILまたは他の回答で提案されているライブラリのいずれかを使用する必要があります。


ファイルの拡張子が正しくない場合はどうなりますか?たとえば、テキストファイルは.jpg拡張子で保存されます(またはその逆)。
hafiz031

1
@ hafiz031あなたが行うことができます実際の形式を取得するにはfrom PIL import Image img = Image.open(filename) print(img.format)、その後、このようにそれを確認しますimg.format.lower() in ['png', 'jpg', 'jpeg', 'tiff', 'bmp', 'gif']
tsveti_iko

6

更新

また、GitHubの Pythonスクリプトに次のソリューションを実装しました。

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

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

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

しかし、私の実験では、ワンドは切り詰められた画像を検出しないため、プロンプトなしで灰色の領域として不足しているパーツをロードすると思います。

Imagemagickに、ジョブを作成できる外部コマンドの識別があること知らせましたが、その関数をプログラムで呼び出す方法が見つからず、このルートをテストしていません。

私はいつも事前チェックを実行することをお勧め、チェックファイルサイズをゼロ(または非常に小さい)ではないと、非常にある安価なアイデア:

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

4

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

申し訳ありませんが、libmagicはファイルを調べて、ビットマップの寸法、フォーマットのバージョンなど、フォーマットだけではなく、それについてより多くのことを伝えようとします。したがって、これは「有効性」の表面的なテストと見なされる場合があります。

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


4

libmagic、python-magicへのPythonバインディングを使用して、mimeタイプを確認できます。これにより、ファイルが破損しているか完全な状態であるかはわかりませんが、ファイルの種類を特定できるはずです。


3

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


ああ、あなたは正しいです。それはxmlです。ただし、画像データが埋め込まれています。
Sujoy

2

1つのオプションは、filetypeパッケージを使用することです。

取り付け

python -m pip install filetype

メリット

  1. クイック:画像の最初の数バイトを読み込むことで機能します(マジックナンバーを確認してください)
  2. さまざまなMIMEタイプをサポート:画像、ビデオ、フォント、オーディオ、アーカイブ。

ソリューション例

import filetype

filename = "/path/to/file.jpg"

if filetype.image(filename):
    print(f"{filename} is a valid image...")
elif filetype.video(filename):
    print(f"{filename} is a valid video...")

公式リポジトリの追加情報:https : //github.com/h2non/filetype.py


1

ファイル拡張子の確認は許容できるでしょうか、それともデータ自体が画像ファイルを表すことを確認しようとしていますか?

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


拡張子を確認するだけでは不十分です。txtファイルの名前をjpgなどに変更できるからです。解決策が見つからない場合に限り、xcfとsvgの拡張機能チェックを使用します
Sujoy

当然のことながら、私はあなたのニーズにより適したソリューションを考案する前に、いくつかの明確化を望んでいました。ありがとう!
doomspork 2009年

-1
format = [".jpg",".png",".jpeg"]
 for (path,dirs,files) in os.walk(path):
     for file in files:
         if file.endswith(tuple(format)):
             print(path)
             print ("Valid",file)
         else:
             print(path)
             print("InValid",file)

コードにインデントの問題があり、正しく実行されません。また、コードが問題を解決する理由と方法についての説明を追加することも検討してください。コードのみの回答は、ここに来る将来の読者にとってそれほど役に立ちません。
Tomerikoo

ここでは、Agrparserメソッドを使用しました。
rObinradOO
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.