主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Python: バイナリデータをいじる

                
tags: python
Python: Exifをもったまま画像をリサイズする

 以前、PythonでJPEGをいじるスクリプトを書いた。つまりはバイナリファイルをいじったということ。そのときに調べたことをメモしておく。

まずファイルの読み方は下記のように。読み込みのシンボル"r"に、バイナリデータのシンボル"b"をつけて"rb"とする。あとストリームオブジェクトfを閉じる処理を施しておくこと。Python 2.6以降ならwithを使うのがいいし、それ以前ならtry...finally...を使う。
    filename = r'C:\Users\h\Desktop\paris.jpg'
with open(filename, 'rb') as f:
data = f.read()


データは文字列型で返ってくる。その一部を表示してみる。
>>> data[0:15]
'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00'

\x00-\xffまでの値が敷き詰められており、値に対応するキャラクタがあるときは、キャラクタが表示されている。
>>> "\x4a" == "J"
True
>>> "\x4a\x46\x49\x46" == "JFIF"
True

データの加工をしやすくするため? structというモジュールが用意されている。文字列型をバイナリ値を並べたタプルに変換してくれる。
http://docs.python.org/2/library/struct.html
>>> unpacked = struct.unpack("B"*(len(data)), data)
>>> type(unpacked)
<type 'tuple'>
>>> unpacked[0:15]
(255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 1, 0)



以前にやったJPEGのExifデータの移植は、structを使うわないほうがらくだった。
ExifはJPEGファイルのバイナリデータ中で、"ff e1"という開始記号で始まる。Pythonでファイルを読み込んでこの開始記号を探す場合、文字列型のメソッドを使ってdata_string.find("\xff\xe1")と書けばいい。一方でstructを使うとタプルが返ってくるので、基本的にはfor文で数行にまたがるコードを書かなければならない。データの切り出しや貼り付けぐらいなら文字列型にしておいたほうが、正規表現が使えてデータ探索が容易になる。structを使うなら、データの値をいじりたい場合(たとえばビットマップ画像の輝度値をいじりたいとか)などのようなときに使うのが向いている。

データ加工が済んで、new_dataという変数に新しいバイナリデータを格納したとする。あとは保存となる。open()の2つめの引数に、データの読み込み時と同様に、"b"をつける。だから"w+b"。
        with open(output, "w+b") as f:
f.write(new_data)
            

コメントの投稿

非公開コメント

プロフィール

Matoba

Author:Matoba

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。