1#!env python3
 2
 3import re
 4import os
 5import sys
 6import os.path
 7import argparse
 8
 9from PIL import Image
10
11
12def img2scad(filename, varname, resize, outf):
13    indent = " " * 4
14    im = Image.open(filename).convert('L')
15    if resize:
16        print("Resizing to {}x{}".format(resize[0],resize[1]))
17        im = im.resize(resize)
18    pix = im.load()
19    width, height = im.size
20    print("// Image {} ({}x{})".format(filename, width, height), file=outf)
21    print("{} = [".format(varname), file=outf)
22    line = indent
23    for x in range(width):
24        line += "[ "
25        for y in range(height):
26            line += "{:d}, ".format(pix[x,y])
27            if len(line) > 60:
28                print(line, file=outf)
29                line = indent * 2
30        line += " ],"
31        if line != indent:
32            print(line, file=outf)
33            line = indent
34    print("];", file=outf)
35    print("", file=outf)
36
37
38def main():
39    parser = argparse.ArgumentParser(prog='img2scad')
40    parser.add_argument('-o', '--outfile',
41            help='Output .scad file.')
42    parser.add_argument('-v', '--varname',
43            help='Variable to use in .scad file.')
44    parser.add_argument('-r', '--resize',
45            help='Resample image to WIDTHxHEIGHT.')
46    parser.add_argument('infile', help='Input image file.')
47    opts = parser.parse_args()
48
49    non_alnum = re.compile(r'[^a-zA-Z0-9_]')
50    if not opts.varname:
51        if opts.outfile:
52            opts.varname = os.path.splitext(os.path.basename(opts.outfile))[0]
53            opts.varname = non_alnum.sub("", opts.varname)
54        else:
55            opts.varname = "image_data"
56    size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$')
57    if opts.resize:
58        m = size_pat.match(opts.resize)
59        if not m:
60            print("Expected WIDTHxHEIGHT resize format.", file=sys.stderr)
61            sys.exit(-1)
62        opts.resize = (int(m.group(1)), int(m.group(2)))
63
64    if not opts.varname or non_alnum.search(opts.varname):
65        print("Bad variable name: {}".format(opts.varname), file=sys.stderr)
66        sys.exit(-1)
67
68    if opts.outfile:
69        with open(opts.outfile, "w") as outf:
70            img2scad(opts.infile, opts.varname, opts.resize, outf)
71    else:
72        img2scad(opts.infile, opts.varname, opts.resize, sys.stdout)
73
74    sys.exit(0)
75
76
77if __name__ == "__main__":
78    main()
79