真綿でお昼寝

ときメモGS4のプレイ日記など

イベントパンフレット作成 忘備録 〜Pythonでサークルカット集を作る〜


以下0821に実施したオンリーイベントで配布したパンフレットのメモです。
製作期間2週間くらい?勢いで製本したパンフレット作成記録

はじめに

7月中旬のことだった。
パンフレットを製本すると決めたものの、どういうデザインにするか全く決まってなかった。
デザインを委託するような費用はなく、考えに考えた結果の研究ノートだった。

最初、某キャラクターが、ゲームのオープニングで、顕微鏡を覗いてペンを片手に急いでメモするシーンを見たとき、はっとした。
これは、同業者ではないか?、もしかしたら、彼も研究ノートをつけているのかもしれない。

研究ノートは、生物系の研究だったら必ずつける。実験設定、実験の環境の情報、結果など、研究の不正防止のために記録する。
研究ノート用の特別なノートも販売されていて、中ぬきなどを防止するためにページ数が振ってあり、これがそのまま技術開発の法的証拠になる。(ので値段が高い。)
www.monotaro.com
今は上記のような高級ノートで研究ノートは付けていないが、ルーズリーフに実験結果や計算式を書き殴るような習慣は消えず、今でも毎日ノートをつけている。
これならば、多分一週間でサンプル作れそうだなー。
差し迫った状態だったので、ノートならデザインが多少ダサくても許されるのではないかと思った。
デザインを凝ったりする時間はもうなく、最初に決めた配色パターンを利用して作成した。

パンフレット編集作業

素材作成

サークル配置の素材はエクセルで地図を作った。Pythonで地図を生成しようと思ったら、ピクスクの番地が規則的ではなかったので、手作業です。
サークルカットの行列は面倒だったので、Pythonで生成しました。サークル配置を修正したりしながらのパンフレット作成だったので、サークルカットの集合体を1ページずつ作成するのは面倒だった。1つずれると全部ずれるんですよねー。で、退屈なことはPythonにやらせよう、ということでPythonで処理。
コードは後半に記載してます。
www.oreilly.co.jp

最初は、使い慣れたパワーポイントでサンプルを6時間くらいで作成し、慌てて、校正を手伝ってくださる方に投げた。
この方々がなかったらできなかったと思います。仕事でもないのに、ちゃんとチェックしてくださって本当にありがとうございます。
パワーポイントでは画素が足りないので、その後イラストレーターのアートボードを複数作って入稿用のパンフレットを作成。

イラレで入稿データ作成、印刷所に依頼

B5でサンプルを刷ってみるとPP加工がノートらしさを損ねていたので、PP加工はやめました。
素朴なノートにしたかったので、ザラザラとした一番安い紙にしました。
宝の地図のページをつけたので、あんまりツルツルした紙だと書きにくいなぁとか考えていました。

つるつる

以下の設定でした。

  • 表紙 マットコート紙135kg、本文上質70kg
  • オプション加工: PP加工
  • 製本方法: くるみ製本
  • とじ方:左とじ


サンプルはB5で作成していたが、大きすぎるし予算的にもB6に作り直す羽目に。
断ち切り位置をミスっててページ数が切れたりしていたので内側に。
あとノートの罫線を無視して配置していたので、リサイズして揃えた。

午前1時の格闘、何してんだろうなぁ、と思いつつ全部B6で作り直しました。
ここまででもシンプルすぎて、可読性はいいけどパンフレットとしておしゃれではない状態でした。そのダサさを、ミジンコで誤魔化したつもり。
ここで印刷所がいっぱいになってて、あーーーーコミケかーーーーーーって、なりました。
コミケってそういえばこの時期に、やってたわ。
フライヤーでお世話になったプリントキング社に泣きついて、そのフォーマットに合わせ、可読性が一番大事、と自分に言い聞かせて入稿(午前4時)
午前中にデータ確認してくださってありがたかった。
ちょっとだけ多めに刷って、フロマージュに委託しました。
まぁ、自家通販でも良かったですが、ちょうど仕事の締め切りの山場も来そうだったので。
冊子は無事にお礼としても、ほしい人にも行き渡ってよかったです。データとしても公開し、パンフレットの役割は終わりました。*1

最終的に以下の設定でした。

  • 表紙 表紙はアートポスト180kg、本文上質90kg
  • オプション加工: なし
  • 製本方法: くるみ製本
  • とじ方:左とじ
ツヤ感なくしました。
やっぱ絶妙にダサい気がする

Pythonのglobモジュールと、OpenCVのライブラリを使用したサークルカット集の作成方法。

1.まず、フォルダにサークル配置の順番に画像を保存した。
A_あ1.png、A_あ2.pngという風にファイル名をサークル配置と対応させる。これは手作業で実施。

サークルカットの保存

(いらすとやさんの虫のイラストお借りしました。)

2.フォルダのファイルを参照するモジュールであるPythonのglobを使用して、ファイルの並びを取得。
# 所定のフォルダ内にあるjpgファイルを連続で読み込んでリスト化する

〜
files = glob.glob("./サクカ" + "/*")
print(files)
# 以下のようなパスが保存され、このパスを参照することで画像が表示される仕組み。
# ['./サークルカット/A_あ5.png', './サークルカット/A_あ4.png', './サークルカット/A_あ1.png', './サークルカット/A_あ3.png', './サークルカット/A_あ2.png', './サークルカット/A_い5.png', './サークルカット/A_い4.png', './サークルカット/A_い3.png', './サークルカット/A_い2.png', './サークルカット/A_い1.png', './サークルカット/A_う2.png', './サークルカット/A_う1.png']


3. 予めサークル配置のCSVからサークル名と、サークル配置を取得し、配列に入れる。

# CSVのsample
data_np = np.array([
    ["A", "A", "A", "A", "A", "A", "A", "A", "A", "A",  "A", "A"],
    ["あ1", "あ2", "あ3", "あ4", "あ5", "い1","い2","い3","い4","い5","う1","う2"],
    ["カブトムシ", "クワガタ", "トンボ", "チョウ", "ホタル", "セミ","カナブン","バッタ","カ", "アリ", "カマキリ", "テントウムシ"]
]).T
data = pd.DataFrame(data_np, columns=["エリア", "配置", "サークル名"]
〜
こんな感じのPandas

で、サークル名と配置をto_list()でリスト化する。
4.OpenCVのライブラリのresizeとかつかいつつ、行列状に画像を表示し、保存。
 画像の枚数が割り切れないときは適当にbreakを入れて収める。まとめてコードを表示するとこんな感じ。

import glob

import cv2
import matplotlib as mpl
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from natsort import natsorted
from PIL import Image
mpl.rcParams['font.family'] ='Hiragino Sans'


data_np = np.array([
    ["A", "A", "A", "A", "A", "A", "A", "A", "A", "A",  "A", "A"],
    ["あ1", "あ2", "あ3", "あ4", "あ5", "い1","い2","い3","い4","い5","う1","う2"],
    ["カブトムシ", "クワガタ", "トンボ", "チョウ", "ホタル", "セミ","カナブン","バッタ","カ", "アリ", "カマキリ", "テントウムシ"]
]).T
data = pd.DataFrame(data_np, columns=["エリア", "配置", "サークル名"]


circle = data["サークル名"].to_list()
haichi = data["配置"].to_list()
area = "A"


# タイル状に col × row 枚配置
col = 3
row = 4

# サークル数 ÷ 12枚、生成する画像の枚数
png_n = len(data) // 12
# 所定のフォルダ内にあるjpgファイルを連続で読み込んでリスト化する
files = glob.glob("./サクカ" + "/*")
# 空の入れ物(リスト)を準備
d = []
n = 0
n_picture = 0 

# ファイル名が数字の場合、natsortedで
# 自然順(ファイル番号の小さい順)に1枚づつ読み込まれる
for i in natsorted(files):
    img = Image.open(i)
    img = np.asarray(img)
    img = cv2.resize(img, (300, 300), cv2.INTER_LANCZOS4)
    d.append(img)

# タイル状に画像を一覧表示
for m in range(png_n): #ループを回す
    fig, ax = plt.subplots(row, col, figsize=(10, 15))
    fig.subplots_adjust(hspace=0.2, wspace=0.2)
    
    for i in range(row):
        for j in range(col):
            print(i,j)
            ax[i, j].xaxis.set_major_locator(plt.NullLocator())
            ax[i, j].yaxis.set_major_locator(plt.NullLocator())
            ax[i, j].imshow(d[n_picture+col*i+j]) #cmap="bone"
            ax[i, j].text(0, -12,  str(area) + " " + str(haichi[n]) + " " + str((circle[n])), fontsize=14)# 追加した行
            n += 1

            # if (i==2) & (j==2): サークルカット数が割り切れないときは、止めたい配置を適当な位置で記載してBreakしループから抜ける。
            #     break

    #保存
    plt.savefig(f"./output/サークルカット.png", format="png", dpi=300, facecolor="w", edgecolor="w")
 #  複数枚出力するときは、一枚あたりのindexを足して更新する。
    #n_picture += 12 
虫のサークルカット

この設定だと背景は透過されているので、融通きいててよかったかも。

以上まとめでした。ちょっと無茶してしまったけど、今ではいい思い出です。

*1:作ってよかったかはしらんけど。