PyOpenGL 6 (バイナリファイル入出力)
バイナリファイル入出力
バイナリファイル入出力に使用するメソッドは以下の通りです。
- open(ファイル名, モード)
- ファイル名のファイルをモードにしたがって開いて、ファイル記述子を返します。
- 'r'
- 読み込み専用
- 'w'
- 書き込み専用
- 'a'
- ファイルの末尾に追加
- 'r+'
- 更新(読み取りと書き込み)
- 'w+'
- ファイルを空にして、そのファイルを読み書き用に開く
- 'a+'
- ファイルを読み書き用に開いて、ファイルの末尾に追加
- 'b'
- ファイルをバイナリモードで開く
(他のオプションと一緒に使用)
- read()
- ファイルのデータをすべて読み込みます。
返り値は、文字列です。
- read(n)
- ファイルのデータをnバイト分読み込みます。
- write(s)
- 文字列またはリスト s をファイルに書き込みます。
- close()
- ファイルを閉じます。
ファイル入出力の例 (バイナリファイル)
読み込んだバイナリの画像データを、半分の明るさにして出力するスクリプトです。
- 以下のスクリプトを、darken.py というファイル名で保存します。
#!env python
import sys
import struct
infile = open(sys.argv[1], 'r')
outfile = open(sys.argv[2], 'w')
for i in range(3):
d = infile.readline()
outfile.write(d)
data = infile.read()
odata = ''
for i in range(len(data)/3):
r = ord(data[3*i])/2
g = ord(data[3*i+1])/2
b = ord(data[3*i+2])/2
odata += struct.pack('BBB', r, g, b)
outfile.write(odata)
infile.close()
outfile.close()
- サンプルの画像をバイナリのppmファイルで用意します。
サンプル画像(tmp1.ppm)
- 以下のように実行します。
# python darken.py tmp1.ppm tmp2.ppm
サンプル画像(tmp2.ppm)
スクリプト解説
import struct
- packメソッドを使用するために、structモジュールをインポートします。
for i in range(3):
- 画像ファイルのヘッダ部分を入出力するためにループします。
ここでは、入力•出力の画像ファイルは同じ大きさ•色数なので、そのままデータを入出力します。
d = infile.readline()
- ヘッダ部分を1行読み込みます。
outfile.write(d)
- 読み込んだヘッダをそのまま出力します。
data = infile.read()
- 画像ファイルの色データを読み込みます。
data に代入されるデータは、文字列として読み込まれています。
odata = ''
- 出力データを入れてゆく変数を用意します。
for i in range(len(data)/3):
- ループの回数は、読み込んだデータの長さを3で除算したものになります。
r = ord(data[3*i])/2
g = ord(data[3*i+1])/2
b = ord(data[3*i+2])/2
- 文字データdata[3*i], data[3*i+1], data[3*i+2]をord()によって数値に変換してRGBの計算を行います。
odata += struct.pack('BBB', r, g, b)
- 三つの数値 r, g, b を1バイトずつのデータに並べて、
odata に追加します。
outfile.write(odata)
- 出力ファイルにデータを書き込みます。
RGBデータのループ
RGBのデータをループによって計算するには、以下の方法もあります。
for rgb in zip(data[0::3], data[1::3], data[2::3]):
r = ord(rgb[0])/2
g = ord(rgb[1])/2
b = ord(rgb[2])/2
for rgb in zip(data[0::3], data[1::3], data[2::3]):
- 入力データから、RGBのデータを一つずつ取り出して、
リスト rgb に代入しながらループします。
rgb には、色データが文字になって並んでいます。
[赤の数値を表す文字, 緑の数値を表す文字, 青の数値を表す文字]
例えば、R が 97、G が 100、B が 120 という値だとすると、
97 は'a'、100 は 'd'、120 は 'x'という文字を表す数値なので、
rgb には以下のようにデータが代入されています。
['a', 'd', 'x']
r = ord(rgb[0])/2
g = ord(rgb[1])/2
b = ord(rgb[2])/2
- 文字データrgb[0], rgb[1], rgb[2]をord()によって数値に変換して計算を行います。
PPM ファイルフォーマット
バイナリデータのPPM画像ファイルは、
文字列3行分のヘッダと、それ以下のバイナリ画像データによって作られています。
- 1行目
- マジックナンバーを表す文字列'P6'
- 2行目
- 横•縦の解像度
例えば、横640ピクセル、縦480ピクセルならば
'640 480'
という文字列になります。
- 3行目
- 色数の最大値
例えば、各色データが1バイトで表される場合は'255'になります。
- 4行目
- 色データがバイナリで並ぶ
色数の最大値が255ならば、1バイトずつRGBの3バイトデータが必要な個数だけ並びます。
練習問題
- 前回のスクリプトを参考にして、テクスチャファイルを読み込むことができるようにしてみましょう。
# python pyopengl17.py sphere.obj tmp3.ppm
tmp3.ppm
4 キーを押したとき
5 キーを押したとき
6 キーを押したとき
上図のOBJデータ
(提出ディレクトリ)
aa1001xx.py というファイル名で以下のフォルダにコピーしてください。
Z:\10AA\プログラム技術研究4\pyopengl17
参考
Prev | Next
index | home
abetmhr@gmail.com