ちょろわざ集
基本的にリファレンスに載っているんだけどね
tags: | python, tips, experiment |
---|---|
created: | 2007-08-05T20:24:24 |
良く使うけどリファレンスから探すのメンドクサイ。 ちょろわざ
変換編
1文字をキャラクターコード(整数)へ
>>> ord('A')
65
キャラクターコード(整数)から1文字へ
>>> chr(65)
'A'
n進数文字列から整数へ
>>> int('01010001', 2) # 2進数文字列を整数に
81
>>> int('77feff', 16) # 16進数文字列を整数に
7864063
>>> int('77feFF', 16) # 大文字小文字混在OK
7864063
>>> int('32467102', 8) # 8進数文字列を整数に
6975042
>>> int('XYZ', 36) # 36進数までOK
44027
文字列から文字リストへ
>>> input = 'hoge'
>>> output = list(input)
>>> output
['h', 'o', 'g', 'e']
文字リストから文字列へ
>>> input = ['h', 'o', 'g', 'e']
>>> output = ''.join(input)
>>> output
'hoge'
辞書から「キー・値ペアのリスト」へ
>>> input = {'hoge':123, 'moge':456}
>>> output = input.items()
>>> output
[('moge', 456), ('hoge', 123)]
「キー・値ペアのリスト」から辞書へ
>>> input = [('hoge', 123), ('moge', 456)]
>>> output = dict(input)
>>> output
{'moge': 456, 'hoge': 123}
キーリストと値リストを「キー・値ペアのリスト」へ
>>> key_list = ['hoge', 'moge']
>>> value_list = [123, 456]
>>> output = zip(key_list, value_list)
>>> output
[('hoge', 123), ('moge', 456)]
文字列/パス名/URI加工編
すべて小文字に
>>> input = 'hoge@HOGE.com'
>>> output = input.lower()
>>> output
'hoge@hoge.com'
すべて大文字に
>>> input = 'hoge@hoge.com'
>>> output = input.upper()
>>> output
'HOGE@HOGE.COM'
セパレータの手前だけを取り出す
>>> input = 'hoge@hoge.com'
>>> output = input.split('@',1)[0]
>>> print output
hoge
セパレータが入力に含まれないなら入力のままが出力。
セパレータの後ろだけを取り出す
>>> input = 'hoge@hoge.com'
>>> output = input.rsplit('@',1)[-1]
>>> print output
hoge.com
セパレータが入力に含まれないなら入力のままが出力。
セパレータを含む分割(Py2.5)
>>> 'moge.hoge.com'.partition('.')
('moge', '.', 'hoge.com')
>>> 'moge.hoge.com'.rpartition('.')
('moge.hoge', '.', 'com')
ファイル名から絶対フォルダ名を取得
>>> file_name = '../../moge/hoge.txt'
>>> import os
>>> os.path.dirname(os.path.abspath(file_name))
'C:\\Temp\\Hoge\\moge'
file_nameが相対パスの場合、内部で「os.getcwd()」を 利用して解決してくれます。 パスセパレータにはバックスラッシュ「\」でも スラッシュ「/」でも問題ありませんが、 バックスラッシュ「」を記述する際は Pythonのシンタックスに従い「’\\’」と記述してください。
>>> file_name = u'../../moge/hoge.txt'
>>> import os
>>> os.path.dirname(os.path.abspath(file_name))
u'C:\\Temp\\Hoge\\moge'
このように入力にunicode文字列を利用すると結果もunicode文字列になります。 パス文字列をunicode文字列で扱うようにしておくと、 要所で「sys.getfilesystemencoding()」の値を利用して ファイルアクセスしてくれます。
拡張子を変更する
>>> file_name = '../../moge/hoge.txt'
>>> import os
>>> os.path.splitext(file_name)[0] + '.log'
'../../moge/hoge.log'
ファイル/プロセス操作編
ファイルの作成日時・更新日時を取得
>>> import os
>>> ctime = os.path.getctime('test.txt') # 作成日時
>>> mtime = os.path.getmtime('test.txt') # 更新日時
ファイルの作成日時・更新日時を設定
>>> import os, time
>>> ctime = mtime = time.time()
>>> os.utime('test.txt', (ctime, mtime))
別のプロセスを起動して標準入出力を利用
>>> args = ['python', '-c', 'print raw_input()']
>>> from subprocess import Popen, PIPE
>>> proc = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
>>> proc.stdin.write('input text')
>>> proc.stdin.close()
>>> proc.wait()
0
>>> print proc.stdout.read()
input text
>>> print proc.stderr.read()
>>>
イメージ操作編
PILモジュールのインストールが必要です。
フォーマット変換
拡張子からイメージハンドラが自動的に選択されます。 下記の例はPNGからJPEGへ。
>>> from PIL import Image
>>> Image.open('test.png').save('test.jpg', quality=50)
jpegの場合、「quality」オプションが使える。 意味のある値の範囲は1~100。
新規作成
>>> from PIL import Image
>>> new_image = Image.new('RGB', (4,4), 0x434241)
色指定は下位8ビットが赤の輝度で、下位から「RGBA」の順番です。
注釈
主なフォーマット
- ‘1’
- モノクロ2値画像
- ‘L’
- グレースケール画像
- ‘P’
- パレットインデックス画像(2色~256色)
- ‘RGB’
- 24ビットカラー画像
- ‘RGBA’
- 24ビットカラー+8ビットアルファ画像
- ‘YCbCr’
- YUV444フォーマット画像(輝度、色相B、色相R各8ビット)
生データの取り出し
>>> from PIL import Image
>>> new_image = Image.new('RGB', (4,4), 0x434241)
>>> new_image.tostring()
'ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC'
「RGBフォーマット」なら「RGB」で、 「RGBAフォーマット」なら「RGBA」の順番です。
長さは「len(フォーマット名)×横幅×高さ」になります。
1BPP画像を反転マスク生データに変換
>>> from PIL import Image
>>> new_image = Image.new('1', (8,8), 0)
>>> new_image.tostring()
'\x00\x00\x00\x00\x00\x00\x00\x00'
>>> new_image.tostring('raw', '1;I', 4, -1)
'\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00\x00\x00'
前者のtostringでは画像の上端から順番に2値画像データを出力します。 後者のtostringではエンコーダーに細かい指定をしています。
Windowsのマスクパターンデータなどは面倒な制約がいろいろありますが、 この対応策が「PIL」には備えられていました。
2番目のパラメータに普通は元画像のフォーマット「‘1’」を指定しますが、 反転マスクを出力するには「‘1;I’」を指定します。 すると、ピクセルの「0」と「1」が反転します。
3番目のパラメータには「ストライド」、 つまりバイトアライメント値を指定します。 4を指定するとライン単位で4バイト境界に足りない部分を0で埋めます。
4番目のパラメータには画像の出力方向を指定します。 内部でラインカウントする時の増分値です。 省略時は「1」になります。 Windowsビットマップなどでは上下が逆ですので 「-1」を指定してやると上下逆に出力します。
今回の例は「1BPP画像」に「rawエンコーダ」を 指定した時だけに使える例です。 元画像のフォーマットとエンコーダの組み合わせ毎に 指定できるパラメータ範囲が変わります。
警告
いくつかのケースでストライドを 0以外にしたときランタイムエラーが。
というわけで、自力でアライメント補正するコード。
def get_windows1bpp_stream(img):
stream = img.tostring('raw','1', 0, -1)
step = (img.size[0]+7)/8
fix = (4-(img.size[0]+7)/8)%4
res = []
for i in range(0, len(stream), step):
res.append(stream[i:i+step])
res.append('\x00'*fix)
return 1, '', ''.join(res)
生データからの作成および確認
>>> from PIL import Image
>>> stream = 'ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC'
>>> new_image = Image.fromstring('RGB', (4,4), stream)
>>> new_image.show()
streamに期待される長さは「len(フォーマット名)×横幅×高さ」で、 この長さに満たない場合エラーになります。(余計な分は無視されます。)
Windowsの場合イメージビューアが起動します。 show()メソッドはビューアが閉じられるまで ブロックします(リターンしてこない)。
アルファチャネルを使った貼り付け
- サンプル画像「’test.png’」:
(このPNG画像にはアルファチャネルを含んでいます。)
>>> from PIL import Image
>>> image = Image.open('test.png')
>>> new_image = Image.new('RGB', image.size, 0xffffff)
>>> new_image.paste(image, mask=image)
>>> new_image.save('test.bmp')
- 出力結果「’test.bmp’」:
maskパラメータを指定するのがミソ。 maskとして渡された場合アルファチャネルデータのみ参照します。 mask指定しないとアルファチャネルごと貼り付けられます。
ちなみにmaskに1BPP画像を指定すると、切り抜き合成されます。 (カラーキー合成と同等の低クオリティ)
減色処理
- サンプル画像「’main_icon.png’」:
>>> from PIL import Image
>>> image = Image.open('main_icon.png')
>>> image.convert('RGB').quantize(16).save('main_icon.bmp')
- 16色画像「’main_icon.bmp’」:
quantizeの最初のパラメータには2~256が使えます。 quantizeが返すイメージはパレットイメージになります。
閾値を使った2値化
- サンプル画像「’test2a.png’」:
>>> from PIL import Image
>>> image = Image.open('test2a.png')
>>> def filter(col):
... if col>220:
... return 255
... else:
... return 0
...
>>> new_image = image.point(filter)
>>> new_image.save('test2b.png')
- 出力結果「’test2b.png’」: