Last active
May 18, 2021 08:31
-
-
Save eruffaldi/1e95c5fef80c0feda105 to your computer and use it in GitHub Desktop.
Multiple Aruco PDF Marker generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cairo,argparse,random | |
#TEST: https://jcmellado.github.io/js-aruco/getusermedia/getusermedia.html | |
#http://terpconnect.umd.edu/~jwelsh12/enes100/markergen.html | |
#http://terpconnect.umd.edu/~jwelsh12/enes100/markers.js | |
markers_opts = [[False,True,True,True,True],[False,True,False,False,False] | |
,[True,False,True,True,False],[True,False,False,False,True]]; | |
import string | |
digs = string.digits + string.letters | |
def int2base(x, base): | |
if x < 0: sign = -1 | |
elif x == 0: return digs[0] | |
else: sign = 1 | |
x *= sign | |
digits = [] | |
while x: | |
digits.append(digs[x % base]) | |
x /= base | |
if sign < 0: | |
digits.append('-') | |
digits.reverse() | |
return ''.join(digits) | |
def drawMarker(canvas,id,sw,sh,x,y): | |
id = int2base(id,4).zfill(5) # 0 padded 5 digits | |
rows = [int(q) for q in id] # as integers | |
#print "marker",id,"at",x,y,"sized",sw,sh,rows | |
sw = sw/7.0 | |
sh = sh/7.0 | |
#val = padDigits(Number(id).toString(4),5); | |
#rows = /(\d)(\d)(\d)(\d)(\d)/.exec(val).slice(1,6); | |
#ctx = canvas.getContext('2d'); | |
#pad = canvas.pad;// || 15; | |
#sw=(canvas.width - (pad*2))/7; | |
#sh=(canvas.height - (pad*2))/7; | |
#background white | |
for h in range(0,7): | |
for w in range(0,7): | |
if (w==0 or h==0 or h==6 or w==6): | |
black = True | |
elif markers_opts[rows[h - 1]][w - 1]: | |
black = True | |
else: | |
black = False | |
# draw rectangle at ... w*sw+pad h*sh+pad sized sw,sh | |
# filled and stroken in white or black ... | |
if black: | |
ctx.set_source_rgb(0,0,0) | |
else: | |
#continue | |
ctx.set_source_rgb(1,1,1) | |
ctx.rectangle(w*sw + x,h*sh + y,sw,sh); | |
ctx.stroke(); | |
ctx.rectangle(w*sw + x,h*sh + y,sw,sh); | |
ctx.fill(); | |
if __name__ == '__main__': | |
import argparse | |
pages = dict(A4=(210,297),A3=(297,420)) | |
parser = argparse.ArgumentParser(description='Aruco Page Maker to PDF, Emanuele Ruffaldi 2015') | |
parser.add_argument('--page', default="A4", help='page size: A4 or A3') | |
parser.add_argument('--pages',default=1,type=int,help="number of pages") | |
parser.add_argument('--landscape', dest='landscape', action='store_const',const=True,default=False,help="set landscape") | |
parser.add_argument('--portrait', dest='landscape', action='store_const',const=False,default=False,help="set landscape") | |
parser.add_argument('--markersize', type=float,default=35,help="marker size (mm)") | |
parser.add_argument('--bordersize', type=float, default=10,help="bourder around marker (mm)") | |
parser.add_argument('--spacing', type=float,default=2,help="marker spacing in vertical and horizontal (mm)") | |
parser.add_argument('--pagemargin', type=float,default=15,help="spacing default around (mm)") | |
parser.add_argument('--fill', action="store_true",help="fills the page") | |
parser.add_argument('--rows', type=int,default=5,help="fill rows") | |
parser.add_argument('--cols', type=int,default=3,help="fill cols") | |
parser.add_argument('--first', type=int,default=100,help="first id") | |
parser.add_argument('--last', type=int,default=110,help="last id") | |
parser.add_argument('--repeat', type=bool,default=False,help="repeat mode (ends at last)") | |
parser.add_argument('--count', type=int,default=0,help="count (alternative to last)") | |
parser.add_argument('--border', action='store_true',help="draws black border around") | |
parser.add_argument('--pageborder', action='store_true',help="draws black border around") | |
parser.add_argument('--axis', action='store_true',help="highlights axis") | |
parser.add_argument('--random', action='store_true',help="randomize markers for board (and produces the randomization)") | |
parser.add_argument('--output',default="output.pdf",help="outputfilename") | |
args = parser.parse_args() | |
page = pages[args.page] | |
if args.landscape: | |
page = (page[1],page[0]) | |
if args.count != 0: | |
args.last = args.first + args.count - 1 | |
else: | |
args.count = args.last - args.first + 1 | |
mm2pts = 2.83464567 | |
lw = 0.5 # mm | |
lwdef = 0.5 | |
bordercolor = (0.5,0.5,0.5) | |
if args.fill: | |
args.cols = (page[0]-args.pagemargin*2)/(args.markersize+args.bordersize*2+args.spacing) | |
args.rows = (page[1]-args.pagemargin*2)/(args.markersize+args.bordersize*2+args.spacing) | |
print "fill results in rows x cols",args.rows,args.cols | |
bid = 0 | |
width_pts, height_pts = page[0]*mm2pts,page[1]*mm2pts | |
surface = cairo.PDFSurface (args.output, width_pts, height_pts) | |
ctx = cairo.Context (surface) | |
ctx.scale(mm2pts,mm2pts) | |
done = False | |
n = args.pages*args.rows*args.cols | |
if args.count < n: | |
n = args.count | |
markers = [args.first+i for i in range(0,n)] | |
if args.random: | |
random.shuffle(markers) | |
open(args.output+".txt","w").write(" ".join([str(x) for x in markers])) | |
for p in range(0,args.pages): | |
if done: | |
break | |
if args.pageborder: | |
ctx.set_source_rgb(*bordercolor) | |
ctx.set_line_width(lw) | |
ctx.rectangle(args.pagemargin,args.pagemargin,page[0]-args.pagemargin*2,page[1]-args.pagemargin*2) | |
ctx.set_line_width(lwdef) # default | |
ctx.stroke() | |
y = args.pagemargin | |
for r in range(0,args.rows): | |
x = args.pagemargin | |
if done: | |
break | |
for c in range(0,args.cols): | |
id = markers[bid % len(markers)] | |
if not args.repeat and bid >= len(markers): | |
done = True | |
break | |
drawMarker(ctx,id,args.markersize,args.markersize,x + args.bordersize,y + args.bordersize) | |
bid = bid + 1 | |
if args.border: | |
ctx.set_source_rgb(*bordercolor) | |
ctx.set_line_width(lw) | |
ctx.rectangle(x,y,args.markersize + args.bordersize*2,args.markersize + args.bordersize*2) | |
ctx.set_line_width(lwdef) # default | |
ctx.stroke() | |
if args.axis: | |
ctx.set_source_rgb(0, 0, 0) | |
ctx.select_font_face("Arial", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) | |
(ax, ay, awidth, aheight, adx, ady) = ctx.text_extents("y>") | |
ctx.move_to(x + args.markersize -ax/mm2pts+args.bordersize-awidth/mm2pts,y-aheight*0.4) | |
ctx.show_text("y>") | |
(ax, ay, awidth, aheight, adx, ady) = ctx.text_extents("y") | |
ry0 = y +aheight*0.6 + args.markersize | |
rx0 = x + -awidth*1.2 | |
ctx.move_to(rx0, ry0) | |
#ctx.show_text("v") | |
ry0 += aheight | |
ctx.move_to(rx0, ry0) | |
ctx.show_text("x") | |
ry0 += aheight | |
ctx.move_to(rx0, ry0) | |
ctx.show_text("v") | |
x = x + args.bordersize*2+args.markersize + args.spacing | |
y = y + args.markersize + args.bordersize*2 + args.spacing | |
ctx.show_page() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added axis flag to show X and Y