LoginSignup
2
2

More than 1 year has passed since last update.

画像ファイルが JPEG 2000 形式かどうかを簡易的に判別する

Last updated at Posted at 2022-02-16

やりたいこと

画像ファイルが JPEG 2000 形式かどうかを判別したい。本来は JPEG 2000 形式の画像ファイルは拡張子が .jp2 である。しかし、拡張子が .jpg だったり MIME タイプが image/jpeg だったりしても、実際は JPEG 2000 形式である場合がある。そこで、バイナリデータを確認して判断する。

方法

マジックナンバー (フォーマット識別子) で判断する。RFC 3745 - MIME Type Registrations for JPEG 2000 (ISO/IEC 15444) には

Magic number(s): 12 byte string: X'0000 000C 6A50 2020 0D0A 870A' (for all JPEG-2000 family files)

と記載されているので、それに則る。

Ruby

def jpeg_2000?(binary_string)
  magic_number = %w(00 00 00 0C 6A 50 20 20 0D 0A 87 0A).join

  binary_string[0...12].unpack1('H*').upcase == magic_number
end
require 'pathname'

# ~/Downloads/JPEG.jpg は JPEG 形式。
jpeg_image = Pathname(Dir.home).join('Downloads/JPEG.jpg')
jpeg_2000?(jpeg_image.binread)
#=> false

# ~/Downloads/JPEG_2000.jpg は JPEG 2000 形式 (だが拡張子は .jpg) 。
jpeg_2000_image = Pathname(Dir.home).join('Downloads/JPEG_2000.jpg')
jpeg_2000?(jpeg_2000_image.binread)
#=> true

Python

import binascii

def is_jpeg_2000(bytes):
    magic_number = '00 00 00 0C 6A 50 20 20 0D 0A 87 0A'
    return binascii.hexlify(bytes[0:12]).decode('utf-8').upper() == ''.join(magic_number.split())
import os

# ~/Downloads/JPEG.jpg は JPEG 形式。
jpeg_image = os.path.join(os.environ['HOME'], 'Downloads/JPEG.jpg')
with open(jpeg_image, 'rb') as f:
    is_jpeg_2000(f.read()) # False

# ~/Downloads/JPEG_2000.jpg は JPEG 2000 形式 (だが拡張子は .jpg) 。
jpeg_2000_image = os.path.join(os.environ['HOME'], 'Downloads/JPEG_2000.jpg')
with open(jpeg_2000_image, 'rb') as f:
    is_jpeg_2000(f.read()) # True

バージョン情報

$ ruby -v
ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [arm64-darwin21]

$ python --version
Python 3.10.2
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2