万博チケットを3Dプリンタで印刷してみた

3Dプリンタ

チケットを印刷したい

現金非対応や地図の配布なしなど、電子への移行が推奨されている関西万博だが、筆者は自分のスマホを信頼していないので、チケットまで電子に頼るのは少し怖い。

幸い、万博チケットのQRコードは一度発行されると変化しないので、事前に印刷しておいても問題ない。

しかし、筆者の手元にはプリンタがない。いや、3Dプリンタなら隣にあるじゃないか!

ということで、QRコードの3D化をやってみた。

元データ

万博のマイチケットからQRコードを表示し、それをスクショ。このPNGをもとに厚みを付けて3D化する。

筆者はプログラミングができないので、コードはChat GPTによるもの。

Pythonスクリプト

失敗①:全ドットに厚みを付ける

最初に、PNGのドット1つ1つを立方体のポリゴンにすればいいじゃん!とかいう雑なスクリプトを試してみた。

しかし、とんでもなく重たいモデルになってしまい、スライサーに取り込むだけで時間がかかるような状態で、3Dデータとしては扱いにくかった。

失敗➁:SVG化

ラスターが駄目ならベクターだーー!!

というノリで2値画像を処理して、SVG化するというスクリプトを作り(ChatGPTが)、それに厚みを付けて3D化した。

直線で構成されているデータなので、SVG化できればそれが一番良い……と思ったが、一筋縄ではいかず、直線部分がギザギザになってしまった。

成功したスクリプト

最終的に、

  1. 画像を読み込む
  2. QRコード部分だけ切り抜く(余白を除去)
  3. QRのセル(黒白のマス目)ごとにリサイズして2値化する
  4. 黒セルを小さな直方体(ボクセル)として配置
  5. 直方体をまとめて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のロック画面に設定しており、これもよさそうだった。

タイトルとURLをコピーしました