30
1 本気でPythonで 宛名書きした話 山田 聡@denzowill #stapy 2016/3/8

本気でPythonで宛名書きした話

Embed Size (px)

Citation preview

1

本気でPythonで宛名書きした話

山田 聡@denzowill#stapy 2016/3/8

2

WHO ARE YOU

● DBエンジニア@株式会社アシスト● ノンプログラマ● 開発業務未経験● Python触って2年(3年?)くらい

● LT専門

3

こんな話してました

4

前回は本チャンでpsycopg2の話をさせていただきました

会社のBlogにももうちょっと細かい話で投稿しましたhttp://www.ashisuto.co.jp/db_blog/article/20160308_postgresql_with_python.html

5

タダの宣伝でした。

6

本題

7

こういうデータを

8

こうしたかった

9

Pythonで宛名書き

●CSVを読んで●ディクショナリのリストにして●Pillowで書き出す!

10

https://pillow.readthedocs.org/en/3.1.x/

Pillow

11

Pillow

●PILというPython画像ライブラリのFork●こっちのほうが継続メンテされてる●PILと互換性あるので同じメソッドで動く●今回の主役

12

流れ

CSVをデータに はがきサイズの白いキャンパス作成

住所書いて書きこみ位置をry

名前書いて書きこみ位置をry

連名があればそれも書く画像を保存

郵便番号書いて書きこみ位置をずらす

13

実は同じ内容で前回LTしました

14

実は同じ内容で前回LTしましたが

コードをちゃんと書き直しました

https://github.com/denzow/print_label

15

実は同じ内容で前回LTしましたが

コードをちゃんと書き直しました

https://github.com/denzow/print_label

縦書きもあるといいねっていわれたから!

16

Pillowで文字を書くには

●フォントファイル指定●書き込みの基準位置(x,y)を指定●draw.textで書き出す

17

Pillowで文字を書くには

●フォントファイル指定●書き込みの基準位置(x,y)を指定●draw.textで書き出す●書き出しは横書きで

18

縦書きするには

●1文字ずつ区切る(2系ならunicode)●書き出し毎にサイズを確認する●サイズ分だけ書き出し位置をずらす

19

img = PIL.Image.new("RGB", VERTICAL_CANVAS_SIZE, (0xff, 0xff, 0xff))draw = PIL.ImageDraw.Draw(img)write_posit = [0, 0]for character in u"東京都千代田区九段北9-9-9 市ヶ谷どっかビル": txt_size = list(draw.font.getsize(character)) draw.text(write_posit, character, (0, 0, 0)) # 書いた分だけY軸をずらす write_posit[1] += txt_size[1]

縦書きするには

20

あ。。。

21

img = PIL.Image.new("RGB", VERTICAL_CANVAS_SIZE, (0xff, 0xff, 0xff))draw = PIL.ImageDraw.Draw(img)write_posit = [0, 0]for character in u"東京都千代田区九段北9-9-9 市ヶ谷どっかビル".replace(u"-",u"|"): txt_size = list(draw.font.getsize(character)) draw.text(write_posit, character, (0, 0, 0)) # 書いた分だけY軸をずらす write_posit[1] += txt_size[1]

横棒を縦棒に

22

半角文字がずれて気持ち悪い

23

img = PIL.Image.new("RGB", VERTICAL_CANVAS_SIZE, (0xff, 0xff, 0xff))draw = PIL.ImageDraw.Draw(img)write_posit = [0, 0]# マルチバイト文字のフォント幅を取得one_char_width = self.draw.font.getsize(u" ")[0]for character in u"山田 聡": txt_size = list(draw.font.getsize(character)) if one_char_width > txt_size[0]: # 差分の半分だけX軸ずらせばセンタリングになる tmp_write_posit = write_posit[:] tmp_write_posit[0] += (one_char_width - txt_size[0]) / 2 draw.text(tmp_write_posit, character, (0, 0, 0)) else: draw.text(write_posit, character, (0, 0, 0)) # 書いた分だけY軸をずらす write_posit[1] += txt_size[1]

半角文字のセンタリング

24

北110

北155

25

満足

26

こういうことをいろいろして

./print_label.py data/sample.csv /tmp vertical

27

こういうデータが

28

こうなった(実在の人物とは関係有りません)

29

こうなった(実在の人物とは関係有りません)

30

ご清聴ありがとうございました