🏁

TouchDesignerでQRコード作成

2025/02/28に公開

TouchDesignerでpyqrcodeというPythonパッケージを利用してQRコードを作成します。

https://pypi.org/project/PyQRCode/

検証にはWindowsを使用し、TouchDesignerのバージョンは2023.12120です。

以下の記事を参考にvenvで仮想環境を作成して、pyqrcodeと依存パッケージのpypngをインストールします。
https://satoruhiga.com/post/extending-touchdesigner/

PowerShell
// TouchDesignerのPythonと同じバージョンのPythonを利用する
$ pyenv install 3.11.1
$ pyenv local 3.11.1

// 仮想環境を作成して有効化する
$ python -m venv .venv
$ .\.venv\Scripts\activate

// パッケージをインストールする
$ pip install pyqrcode pypng

QRコードをScript TOPで作成する

pyqrcodeをScript TOPで使用して、QRコードを作成します。

import sys, os

path = os.path.join(os.path.abspath('.'), '.venv/Lib/site-packages')
if not path in sys.path:
	sys.path.append(path)
	print('Append new module search path:', path)

import pyqrcode
import numpy as np
import cv2
import io

def onSetupParameters(scriptOp):
	page = scriptOp.appendCustomPage('QR Code')
	p = page.appendInt('Scale', label='QR Code Scale')
	p[0].normMin = 1
	p[0].normMax = 20
	p[0].default = 5
	p = page.appendStr('Data', label='QR Code Data')
	p[0].default = 'Hello, World!'

def onPulse(par):
	return

def onCook(scriptOp):
	scale = scriptOp.par.Scale.val
	data = scriptOp.par.Data.val
	qrcode = pyqrcode.create(data)
	buffer = io.BytesIO()
	qrcode.png(buffer, scale=scale)
	array = np.frombuffer(buffer.getvalue(), dtype=np.uint8)
	image = cv2.imdecode(array, cv2.IMREAD_COLOR)
	image = np.flipud(image).copy() # copyがないとTDがクラッシュする
	scriptOp.copyNumpyArray(image)

内容によってはQRコード作成の処理がそこそこ重くなるので、cookのタイミングで処理落ちが発生することがあります。

QRコードを画像として保存する

pyqrcodeでQRコードを画像として保存します。Text DATで以下のスクリプトをRun Scriptすると指定したパスにQRコードが作成されます。
作成した画像をMovie File In TOPで読み込めば、TouchDesignerで表示することができます。

import sys, os

path = os.path.join(os.path.abspath('.'), '.venv/Lib/site-packages')
if not path in sys.path:
	sys.path.append(path)
	print('Append new module search path:', path)

import pyqrcode

def save_qrcode(scale, data, path):
	qrcode = pyqrcode.create(data)
	qrcode.png(path, scale=scale)

scale = 20
data = 'Hello, World!'
path = './qrcode.png'
save_qrcode(scale, data, path)

この方法でもScript TOPのときと同様に処理落ちが発生することがあるので、それを避けるために別のスレッドで保存すると以下のようになります。

# pathの追加は省略

import pyqrcode
import threading

def save_qrcode(scale, data, path):
	qrcode = pyqrcode.create(data)
	qrcode.png(path, scale=scale)

scale = 20
data = 'Hello, World!'
path = './qrcode.png'
thread = threading.Thread(target=save_qrcode, args=(scale, data, path))
thread.start()

Discussion