Skip to content

Instantly share code, notes, and snippets.

@davidhoness
Last active September 4, 2016 17:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidhoness/82a778af017423b3c39e62e08b30eb1e to your computer and use it in GitHub Desktop.
Save davidhoness/82a778af017423b3c39e62e08b30eb1e to your computer and use it in GitHub Desktop.
#!/usr/bin/python
from PIL import Image
import struct
import qrcode
import sys
if len(sys.argv) == 4:
qr_data = sys.argv[1]
output_file = sys.argv[2]
page_no = sys.argv[3]
else:
print('Usage: ./tt_qr.py [Qr Data] [File Name] [Page No]')
print('Example: ./tt_qr.py https://goo.gl/ qr.tti 571')
sys.exit(0)
CTRL_CODE = struct.pack('B', 27)
COLOUR_WHITE = struct.pack('B', 87)
COLOUR_RED = struct.pack('B', 65)
FULL_BLOCK = struct.pack('B', 127)
def factor(value, mod):
return value - (value % mod) + mod if value % mod > 0 else value
def read_pixel(pixels, x, y):
try:
return pixels[x, y]
except IndexError:
return 255
def write_ln(f, s):
f.write('%s\r\n' % s)
def output_line(f, line_no):
f.write('OL,')
f.write(str(line_no))
f.write(',')
def blank_line(f, length, colour_code):
f.write(CTRL_CODE)
f.write(colour_code)
for i in range(length):
f.write(FULL_BLOCK)
f.write('\r\n')
qr = qrcode.QRCode(version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=1,
border=0)
qr.add_data(qr_data)
qr.make(fit=True)
qr_img = qr.make_image()
qr_pix = qr_img.load()
tt_gfx_lookup = [
1, 2,
4, 8,
16, 64
]
width, height = qr_img.size
width = factor(width, 2)
height = factor(height, 3)
lines = []
for y in range(0, height, 3):
line = []
for x in range(0, width, 2):
block = []
for block_row in range(3):
block.append(read_pixel(qr_pix, x, y + block_row))
block.append(read_pixel(qr_pix, x + 1, y + block_row))
block_bits = 0
for i in range(6):
if block[i] > 0:
block_bits += tt_gfx_lookup[i]
line.append(block_bits + 32)
lines.append(line)
print(lines)
with open(output_file, 'wb') as f:
write_ln(f, 'DE,QR Code Test')
write_ln(f, 'DS,inserter')
write_ln(f, 'SP,E:\Program Files (x86)\wxTED\qr.tti')
write_ln(f, 'CT,8,T')
write_ln(f, 'PN,%s00' % page_no)
write_ln(f, 'SC,0000')
write_ln(f, 'PS,8000')
write_ln(f, 'RE,0')
output_line(f, 0)
f.write('XXXXXXXXTEDFAX mpp DAY dd MTH ')
f.write(CTRL_CODE)
write_ln(f, 'C hh:nn.ss')
output_line(f, 1)
blank_line(f, len(lines[0]) + 2, COLOUR_WHITE)
for index, line in enumerate(lines):
output_line(f, index + 2)
f.write(CTRL_CODE)
f.write(COLOUR_WHITE)
f.write(FULL_BLOCK)
for block in line:
f.write(struct.pack('B', block))
f.write(FULL_BLOCK)
f.write('\r\n')
output_line(f, index + 3)
blank_line(f, len(lines[0]) + 2, COLOUR_WHITE)
output_line(f, 24)
f.write(CTRL_CODE)
f.write(COLOUR_RED)
write_ln(f, 'Back')
write_ln(f, 'FL,551,551,780,790,8ff,8ff')
@davidhoness
Copy link
Author

davidhoness commented Sep 4, 2016

TTI file format QR code generator

Format spec

Intended for use on Raspberry Pi with Vbit Pi

Prerequisites

sudo apt-get install python-imaging
sudo apt-get install python-qrcode

Download

wget <paste raw link from top right above>
chmod +x tt_qr.py

Run

./tt_qr.py https://goo.gl/ qr.tti 572

Notes

In graphics mode each block is divided into six pixels (2 x 3) that are bitwise enabled. The possible values range from 0x20 to 0x3F but instead of going to 0x40, for the bottom right pixel, it jumps to 0x60 and continues from there to 0x7F. So in deanery you can use the following matrix to bitwise construct the blocks and finally add 32 to finalise.

LBit RBit
1 2
4 8
16 64

You then build the QR code and traverse through it pulling out 2 x 3 slices of pixels and use the matrix above to bitwise construct the teletext blocks (see lines 66 to 82). After that it's just a matter of writing the tti file out to disk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment