コンタクトシート風シートの作成プログラム (決定版)
こんにちは。らずべりーです。 最近めちゃ寒いですね。
コンタクトシート風シート(Adobeさんに気を遣ってぼやかしてみた)の作成プログラムを仕上げてみました。
これまでの経緯
以前書いたコードは画像20枚までのシートを1枚だけ作成するプログラムでした。
plant-raspberrypi3.hatenablog.com
また、テキストを画像にするときにフォントを指定する方法についても書いていました。
plant-raspberrypi3.hatenablog.com
今回はこれらを組み合わせて、画像何枚でも20枚ごとに1枚ずつのシートを作成するためのプログラムを完成させました。これで、撮った画像をまとめて確認&印刷できます(^ ^)ノ
今回、みんなのPythonを参考に、ジェネレータ関数というものをはじめて使ってみました。
みんなのPythonさんには日頃から大変お世話になっております。
非常にわかりやすい入門本なので、すごくすごくおすすめです!!(宣伝)
使用する素材
以下、一例です。(ちっちゃいです。)
今回は古い文献の画像から"The"の文字だけ取り出したものを使用します。個々の文献の内容は含まれず、一般的な字体であるため、特に引用はしません。(すみません。)
将来的に文字認識の機械学習(OCRとか?)をして遊ぶための準備的な。。。
実行環境
macOS Sierra
Python 3.6.1
Pillow 4.3.0
Jupyter lab v0.27.0
あとはNumpyとか。
コード概要
- フォルダパスを指定してファイル名と画像ファイルをバルクで読み出す関数
- 画像をコンタクトシート風シート用にリサイズする関数
- ファイル名の画像を生成(Helvetica,16pt)する関数
- 20個のデータから4列6行のコンタクトシート風シートを1つ作成する関数
- 20個ごとに1つのコンタクトシート風シートを作成するジェネレータ関数
- 上記全ての関数を組み合わせて、画像のフォルダパスからコンタクトシート風シートを自動生成して保存する関数
- 実行
*補足:始める前に、モジュールのインポートをしてください。import os
import numpy as np
from PIL import Image, ImageFont, ImageDraw
の3つが必要です。
実際の手順
1. フォルダパスを指定してファイル名と画像ファイルをバルクで読み出す
def png_bulk_read(path1,format=".png"): os.chdir(path1) all_files = os.listdir(path1) file_names = [i for i in all_files if i.endswith(format)] png_files = [Image.open(i) for i in file_names] return file_names, png_files
2. 画像をコンタクトシート風シート用にリサイズ
def bulk_fig_resize(im_series,scale=200): im_series_resize = [] for i in range(len(im_series)): width = np.array(im_series[i]).shape[0] length = np.array(im_series[i]).shape[1] if width < length: img_i = im_series[i] s_int1 = int(scale*width/length) im_series_resize.append(img_i.resize((scale,s_int1))) else: img_i = im_series[i] s_int2 = int(scale*length/width) im_series_resize.append(img_i.resize((s_int2,scale))) return im_series_resize
ifの後のim_series_resize.append
あたりが崩れてしまいました。
Markdown記法に慣れていないためです、すみません。
ifより1つ後ろにインデントが正解です。
201710/19 18:30ごろ修正しました。
3. ファイル名の画像を生成(Helvetica,16pt)
def file_name_figs(file_names): file_name_fig_list = [] for i in file_names: img_text = Image.new('RGB', (240, 20), (255,255,255)) draw = ImageDraw.Draw(img_text) fontpath = "/System/Library/Fonts/Helvetica.dfont" font = ImageFont.truetype(fontpath, 16) draw.text((0, 0), i, font=font,fill='#000') file_name_fig_list.append(img_text) return file_name_fig_list
4. 20個のデータから4列6行のコンタクトシート風シートを1つ作成
def create_csheet(im_series_resize,text_fig_list): fig_width = 240 fig_length = 265 if len(im_series_resize) <= 20: canvas = Image.new('RGB', (1000, 1350), (255, 255, 255)) for i in range(len(im_series_resize)): tmp_canvas = Image.new("RGB",(fig_width,fig_length),(255,255,255)) tmp_canvas.paste(text_fig_list[i],(0,0)) try: img_i = im_series_resize[i] tmp_canvas.paste(img_i,(0,20), img_i.split()[3]) except IndexError: img_i = im_series_resize[i] tmp_canvas.paste(img_i,(0,20)) canvas.paste(tmp_canvas, (10+int(i%4)*fig_width,10+int(i/4)*fig_length)) else: print("Error") canvas = 0 return canvas
5. 20個ごとに1つのコンタクトシート風シートを作成するジェネレータ関数
def generate_csheet(im_series_resize,text_fig_list): while True: if len(im_series_resize) < 1: break elif len(im_series_resize) < 20: yield create_csheet(im_series_resize,text_fig_list) break else: im_list = im_series_resize[:20] text_list = text_fig_list[:20] im_series_resize = im_series_resize[20:] text_fig_list = text_fig_list[20:] yield create_csheet(im_list,text_list)
6. 画像のフォルダパスからコンタクトシート風シートを自動生成して保存
def csheet_create_from_folder(folder_path): file_names, png_files0 = png_bulk_read(folder_path) png_files = bulk_fig_resize(png_files0) file_figs = file_name_figs(file_names) cs_generater = generate_csheet(png_files,file_figs) cs_list = [] while True: try: cs_list.append(next(cs_generater)) except StopIteration: break for i in range(len(cs_list)): cs_list[i].save("csheet_{}.png".format(i),"PNG",quality=100, optimize=True)
7. 実行
上記の全ての関数をcsheet_module.py
という名前で保存し、モジュールとして呼び出して実行します。
import csheet_module as cs folder_path = "/usr/local/scanned_pdf/the" cs.csheet_create_from_folder(folder_path)
結果
27枚の画像が2枚のコンタクトシート風シートのpngファイルとして保存されました。
1枚目
2枚目
完成!!! (^ ^)ノ