チケットを印刷したい
現金非対応や地図の配布なしなど、電子への移行が推奨されている関西万博だが、筆者は自分のスマホを信頼していないので、チケットまで電子に頼るのは少し怖い。
幸い、万博チケットのQRコードは一度発行されると変化しないので、事前に印刷しておいても問題ない。
しかし、筆者の手元にはプリンタがない。いや、3Dプリンタなら隣にあるじゃないか!
ということで、QRコードの3D化をやってみた。
元データ
万博のマイチケットからQRコードを表示し、それをスクショ。このPNGをもとに厚みを付けて3D化する。
筆者はプログラミングができないので、コードはChat GPTによるもの。
Pythonスクリプト
失敗①:全ドットに厚みを付ける
最初に、PNGのドット1つ1つを立方体のポリゴンにすればいいじゃん!とかいう雑なスクリプトを試してみた。
しかし、とんでもなく重たいモデルになってしまい、スライサーに取り込むだけで時間がかかるような状態で、3Dデータとしては扱いにくかった。
失敗➁:SVG化
ラスターが駄目ならベクターだーー!!
というノリで2値画像を処理して、SVG化するというスクリプトを作り(ChatGPTが)、それに厚みを付けて3D化した。
直線で構成されているデータなので、SVG化できればそれが一番良い……と思ったが、一筋縄ではいかず、直線部分がギザギザになってしまった。
成功したスクリプト
最終的に、
- 画像を読み込む
- QRコード部分だけ切り抜く(余白を除去)
- QRのセル(黒白のマス目)ごとにリサイズして2値化する
- 黒セルを小さな直方体(ボクセル)として配置
- 直方体をまとめて1つの3Dモデルに結合し、STL形式で保存
という手順で処理するスクリプトでQRコードを正しく立体にすることができた。
import numpy as np
from PIL import Image, ImageOps
import trimesh
def qr_image_to_stl_trimmed(image_path, stl_path, qr_cell_count=29, pixel_size=0.4, thickness=1.2):
# 画像を開く・グレースケール化
img = Image.open(image_path).convert("L")
# 画像の周囲をトリミング(余白除去)
img = ImageOps.invert(img) # 白黒反転(白背景→黒)→ bbox取得用
bbox = img.getbbox()
img = ImageOps.invert(img.crop(bbox)) # 反転戻し+切り抜き
# セルサイズに合わせてリサイズ
qr_img = img.resize((qr_cell_count, qr_cell_count), Image.NEAREST)
# セルを2値化:黒=1, 白=0
qr_array = np.array(qr_img)
qr_bin = (qr_array < 128).astype(np.uint8)
voxels = []
for row in range(qr_cell_count):
for col in range(qr_cell_count):
if qr_bin[row, col]:
box = trimesh.creation.box(extents=[pixel_size, pixel_size, thickness])
box.apply_translation([
col * pixel_size,
(qr_cell_count - 1 - row) * pixel_size,
thickness / 2
])
voxels.append(box)
if not voxels:
print("QRコードが空です。")
return
combined = trimesh.util.concatenate(voxels)
combined.export(stl_path)
print(f"STLファイルを出力しました: {stl_path}")
# 使用例(画像を事前に保存したファイル名を指定)
qr_image_to_stl_trimmed("qr.PNG", "qr.stl", qr_cell_count=29)
blenderで加工

カードの板部分やテキストはblenderを使って作成した。
3Dプリント
Bambu Lab A1 miniに0.2mmのノズルを付けて造形。
筆者はAMSを持っていないので、途中で一時停止し、フィラメントを差し替えるという雑な方法で2色刷りをした。

欲張って3枚同時に造形したら反ってしまったので、やはりエンクロージャー付きを買うべきか……(←3Dプリンタを買い替える理由が欲しい人)
万博参戦

実際に万博で使ってみたが、入場ゲート、パビリオン共に問題なく使用できた。
歩きスマホでコードを用意する必要がなく、スムーズに通過できたので予め造形してから万博に行くのはおすすめだ。
ちなみに、同行者はiPhoneのロック画面に設定しており、これもよさそうだった。