Pythonのimghdrライブラリで画像の種類を判別する方法

Pythonのライブラリimghdrを使って、画像の種類を判別する方法を紹介します。このライブラリを使うと、「指定したファイルがPNG画像か?」などを調べることができます。

※確認に使ったPythonのバージョンは3.4.3です。

ファイル名から判定する

imghdrライブラリのwhat関数にファイル名を渡してあげると、画像の種類を表す文字列を取得できます。例えば、/tmp/foo.pngというPNG形式の画像がある場合、what関数でそのパスを与えると「png」という文字列が返ってきます。

what関数で返ってくる文字列はドキュメントで確認することができます。

# coding: utf-8
import imghdr

imagetype = imghdr.what('/tmp/foo.png')
print(imagetype)  # 「png」と表示されます。
print(type(imagetype))  # 「<class 'str'>」と表示されます。

また、/tmp/foo.jpgというJPEG形式の画像の場合、whatの戻り値は「jpeg」になります。

imagetype = imghdr.what('/tmp/foo.jpg')
print(imagetype)  # 「jpeg」と表示されます。

このwhat関数を使うと、ファイル名から「その画像がPNG形式か?」などを調べることができます。

def is_pngfile(filename):
    return imghdr.what(filename) == 'png'

if is_pngfile('/tmp/foo.png'):
    print('PNG形式です。')  # これが表示されます。
else:
    print('PNG形式ではありません。')

if is_pngfile('/tmp/foo.jpg'):
    print('PNG形式です。')
else:
    print('PNG形式ではありません。')  # これが表示されます。

ファイルの拡張子が正しくない場合

例えば、PNG形式の画像「dummy.jpg」があったとします。what関数のファイル名にこれを渡すと、「jpeg」ではなくて「png」が返ってきます。

# 名前は「dummy.jpg」ですが、中身はPNG形式の画像です。
imagetype = imghdr.what('/tmp/dummy.jpg')
print(imagetype)  # 「jpeg」ではなくて「png」と表示されます。

whatで画像ファイル以外を指定

what関数に画像以外のファイルを渡すと、「None」が返ってきます。また、指定したファイルが存在しない場合は、「FileNotFoundError」が投げられます。

imagetype = imghdr.what('/tmp/foo.txt')
print(imagetype)  # 「None」と表示されます。
print(type(imagetype))  「<class 'NoneType'>」と表示されます。

try:
    imghdr.what('/tmp/none.png')
except FileNotFoundError as e:
    print(e)  # 「[Errno 2] No such file or directory: '/tmp/none.png'」と表示されます。

バイト列型から判定する

what関数はファイル名だけではなく、バイト列型を指定することができます。その場合は、そのバイト列型が表す画像の種類を返します。

バイト列型を渡す場合、気持ち悪いですが、what関数の最初の引数(ファイル名)にNoneを渡し、2番目の引数にバイト列型オブジェクトを渡します。

with open('/tmp/foo.png', 'rb') as fp:
    imagedata = fp.read()
imagetype = imghdr.what(None, h=imagedata)
print(imagetype)  # 「png」と表示されます。

また、ファイル名の時と同様に、画像以外のデータも渡すことができます。

text = b'''aaa,bbb
ccc,ddd
eee,fff'''
imagetype = imghdr.what(None, h=text)
print(imagetype)  # 「None」と表示されます。

この記事が役に立った場合、シェアしていただけると励みになります!!