画像ファイルの種類を拡張子だけで判別するのではなく、ファイルの先頭数バイトの情報をチェックして判別する方法です。
はじめに
多くのファイルには先頭にマジックナンバーという識別子を持っています。
ただ、もちろんマジックナンバーがないファイルもあります。
なのですべてのファイルを判別できる完璧な方法ではありません。
拡張子だけで判断するよりも少し正確になるという感じで読んでください。
ここではマジックナンバーで判別できる画像ファイルについて見てみます。
画像ファイルのマジックナンバー
以下の表にあるのが各画像ファイルごとのマジックナンバーです。
拡張子 | バイナリデータ(16進数) | ASCII |
PNG | 89 50 4E 47 | .PNG |
JPEG | FF D8 DD E0 | |
JPG | FF D8 FF EE *JPEGかどうかを確認するにはFF D8で可能 | |
25 50 44 46 | ||
GIF(89a) | 47 49 46 38 39 61 | GIF87a |
GIF(87a) | 47 49 46 38 37 61 *GIFかどうかを確認するには47 49 46(GIF)で可能 | GIF89a |
BMP | 42 4D | BM |
TIFF | 49 49 2A 00 (リトルエンディアン) 4D 4D 00 2A (ビックエンディアン) | II*. MM.* |
WEBP | 52 49 46 46 ?? ?? ?? ?? 57 45 42 50 *??はファイルサイズのため先頭のRIFFから4バイト先のWEBPを確認 | RIFF….WEBP |
Pythonプログラムのサンプルを見てみましょう。(Pythonでサンプルを書いていますが、どの言語でも対応できます。)
入力した名前の画像ファイルを読み込み、マジックナンバーを確認しています。
fname = input('File Name >>')
JPEG = b'\xFF\xD8'
PNG = b'\x89\x50\x4E\x47'
PDF = b'\x25\x50\x44\x46'
GIF = b'\x47\x49\x46'
BMP = b'\x42\x4D'
TIFF_L = b'\x49\x49\x2A\x00'
TIFF_B = b'\x4D\x4D\x00\x2A'
WEBP_F = b'\x52\x49\x46\x46'
WEBP_E = b'\x57\x45\x42\x50'
ftype = None
with open(fname, 'rb') as fin:
byte = fin.read(12)
if byte[:2] == JPEG:
ftype = 'JPEG'
elif byte[:4] == PNG:
ftype = 'PNG'
elif byte[:4] == PDF:
ftype = 'PDF'
elif byte[:3] == GIF:
ftype = 'GIF'
elif byte[:2] == BMP:
ftype = 'BMP'
elif byte[:4] == TIFF_L or byte[:4] == TIFF_B:
ftype = 'TIFF'
elif byte[:4] == WEBP_F and byte[8:12] == WEBP_E:
ftype = 'WEBP'
if ftype is None:
print('Not Image file or can not read it')
else:
print(f'File Type is {ftype}')
上記の表にある画像ファイルの種類をマジックナンバーで判別しています。
実はPythonには標準で画像ファイルの種類を判別できるモジュールがあります。
「imghdr」というモジュールを使えば簡単に判別できます。
ドキュメント:https://docs.python.org/ja/3/library/imghdr.html#module-imghdr
これを使ったサンプルが以下となります。
import imghdr
fname = input('File Name >>')
ftype = imghdr.what(fname)
if ftype is None:
print('Not Image file or can not read it')
else:
print(f'File Type is {ftype}')
imghdr.what()を使って判別します。
ファイル名を渡すだけで判別してくれるので、ファイルを開く必要はありません。
ただ、デフォルトで判別できるファイルの種類は限られています。
増やすこともできるようですが、詳細はわかりません。
マジックナンバーを確認すれば画像ファイルに限らず、ファイルの種別を判別できるので、マジックナンバーを確認するコードは書くことはあるかもしれません。
適応した方法を選ぶといいでしょう。
画像ファイルの種類を確認する方法でした。