画像ファイル種類をマジックナンバーで確認する

画像ファイルの種類を拡張子だけで判別するのではなく、ファイルの先頭数バイトの情報をチェックして判別する方法です。

はじめに

多くのファイルには先頭にマジックナンバーという識別子を持っています。

ただ、もちろんマジックナンバーがないファイルもあります。

なのですべてのファイルを判別できる完璧な方法ではありません。

拡張子だけで判断するよりも少し正確になるという感じで読んでください。

ここではマジックナンバーで判別できる画像ファイルについて見てみます。

画像ファイルのマジックナンバー

以下の表にあるのが各画像ファイルごとのマジックナンバーです。

拡張子バイナリデータ(16進数)ASCII
PNG89 50 4E 47.PNG
JPEGFF D8 DD E0 
JPGFF D8 FF EE
*JPEGかどうかを確認するにはFF D8で可能
 
PDF25 50 44 46%PDF
GIF(89a)47 49 46 38 39 61GIF87a
GIF(87a)47 49 46 38 37 61
*GIFかどうかを確認するには47 49 46(GIF)で可能
GIF89a
BMP42 4DBM
TIFF49 49 2A 00  (リトルエンディアン)
4D 4D 00 2A  (ビックエンディアン)
II*. MM.*
WEBP52 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()を使って判別します。

ファイル名を渡すだけで判別してくれるので、ファイルを開く必要はありません。

ただ、デフォルトで判別できるファイルの種類は限られています。

増やすこともできるようですが、詳細はわかりません。

マジックナンバーを確認すれば画像ファイルに限らず、ファイルの種別を判別できるので、マジックナンバーを確認するコードは書くことはあるかもしれません。

適応した方法を選ぶといいでしょう。

画像ファイルの種類を確認する方法でした。