3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PythonでJPEGのヘッダーから解像度を読み取る

Last updated at Posted at 2019-10-18

##最初に
初投稿です!
自身の備忘と調べたことのアウトプットとして活用していきたいと思います。

JPEG画像から画像の解像度を取り出す必要があったのですが、
プロパティから確認出来るとは言うものの、せっかくなのでpythonの勉強がてら自動で画像を開き、JPEGヘッダーを参照して解像度を抽出するpythonスクリプトを作ってみました。

##開発環境
Windows
python=3.6

##使用する画像
使用する画像はなんでもいいのですが、今回はこちらのフリー素材をお借りしました。
https://pixabay.com/ja/photos/%E6%B2%88%E9%BB%99-%E5%BF%83%E3%81%AE%E5%B9%B3%E5%92%8C-%E3%83%AA%E3%83%A9%E3%82%AF%E3%82%BC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-4522878/

今回はJFIF形式にのみ有効なものとしています。
JFIFの説明は本稿では説明していませんが、下記リンク先にまとめられているので参考にしてください。
https://qiita.com/urakarin/items/e5782dec3d24fb1cec6f
https://memo.studiogaki.com/what-are-exif-and-jfif/

プロパティで開いた時の赤枠内の解像度をpythonで抽出するというのが本稿の内容になります。
↓こちらは上記リンク先のプロパティ画面(test.jpgとリネームしています)
image.png

##pythonスクリプト
早速pythonスクリプトを示します。
時間がない方、基本的なことは分かっているという方は下記pythonスクリプトをコピペしてみてください。
その際にinputというフォルダをpythonスクリプトと同じディレクトリに作成してください。

read_jpegheader_reso.py
import os

"""
メイン
"""
if __name__ == "__main__":
    
    #カレントディレクトリを取得
    current_dir = os.getcwd()
    
    #入力ディレクトリを取得
    indir = current_dir + "\\input\\"
    
    inimg = indir + "test.jpg"
    
    with open(inimg,"rb") as infile:
        
        #dataの中に画像のバイナリ情報を全て入れる
        data = infile.read()

        # JFIF形式であること前提
        wide_reso = data[14:16]
        height_reso = data[16:18]

        # ビッグエンディアン方式で16進数⇒10進数 
        wide_reso_big_10 = int.from_bytes(wide_reso,"big")
        height_reso_big_10 = int.from_bytes(height_reso,"big")
        
        print("wide_reso_big_10:",wide_reso_big_10)
        print("height_reso_big_10:",height_reso_big_10)

重要な箇所のみ解説していきます。
まずはディレクトリや画像のパスの設定です。
今回のスクリプトでは、スクリプトと同じディレクトリに「input」というフォルダを作り、その中に「test.jpg」とリネームした画像を入れることが前提です。


    #カレントディレクトリを取得
    current_dir = os.getcwd()
    
    #入力ディレクトリを取得
    indir = current_dir + "\\input\\"
    
    inimg = indir + "test.jpg"

次に、画像をバイナリモードで開いてdataに格納しています。


    with open(inimg,"rb") as infile:
        
        #dataの中に画像のバイナリ情報を全て入れる
        data = infile.read()

最後に、格納したバイナリ情報から必要となる解像度の情報を抽出します。
JPEGのヘッダー仕様を確認して、水平方向、垂直方向の解像度が書かれたアドレスを指定して抽出しています。
水平方向は14、15バイト目に、垂直方向は16、17バイト目に記載されています。

抽出したものをそのまま表示してもバイナリデータのままなので、10進数に変換を行います。
その際にビッグエンディアン方式で10進数へと変換します。

なお、JPEGヘッダーについてはこちらを参考にさせていただきました。
https://www.setsuki.com/hsp/ext/jpg.htm

ビッグエンディアンはバイトオーダに関する用語になりますが、下記リンク先が参考になります。
http://www.ertl.jp/~takayuki/readings/info/no05.html


        # JFIF形式であること前提
        wide_reso = data[14:16]
        height_reso = data[16:18]

        # ビッグエンディアン方式で16進数⇒10進数 
        wide_reso_big_10 = int.from_bytes(wide_reso,"big")
        height_reso_big_10 = int.from_bytes(height_reso,"big")
        
        print("wide_reso_big_10:",wide_reso_big_10)
        print("height_reso_big_10:",height_reso_big_10)

今回のスクリプトを実行した結果を示します。


wide_reso_big_10: 300
height_reso_big_10: 300

プロパティで確認した結果と一致することが確認出来ました!

##最後に

globを使ってディレクトリ内の画像を順番に選択してヘッダーを参照して解像度を抽出することも可能です。
そして、その出力結果をcsvなどに出力することも可能です。
反響があれば上記のソースコードも追記していこうかなと思っています。

ご指摘があればどうぞよろしくお願いいたします。

3
3
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
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?