The process I came up with is pretty straight forward
- get an image
- crop to 4:3 or any other neat golden mean which you can find a canvas for
- reduce to a small number of pixels, I used 160x120px
- drop to greyscale
- 8 colour palette using dithering
- save as gif
- run it through program below to make a black square for each pixel
- convert SVG to PostScript
- use Poster to blow it up to 4×4 A4 sheets to the size of your canvas
- Print to overhead transperancys, you will get registration points and numbering of the tiles
- cut out all the squares to make stencils
- apply black enamel paint to white canvas
- enjoy the analog digital fusion
- 160×120 pixels means you have to cut out 19200 little squares
Another idea would be to get 8 hole punches and change the code below to indicate what radius hole punch to use
that would cut down on the rsi by at least 80%
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | #!/usr/bin/env python """\ SVG.py - Construct/display SVG scenes. The following code is a lightweight wrapper around SVG files. The metaphor is to construct a scene, add objects to it, and then write it to a file to display it. This program uses ImageMagick to display the SVG files. ImageMagick also does a remarkable job of converting SVG files into other formats. """ import math import os from PIL import Image display_prog = 'display' # Command to execute to display images. class Scene: def __init__(self,name="svg",height=400,width=400): self.name = name self.items = [] self.height = height self.width = width return def add(self,item): self.items.append(item) def strarray(self): var = ["<?xml version=\"1.0\"?>\n", "<svg height=\"%d\" width=\"%d\" >\n" % (self.height,self.width), " <g style=\"fill-opacity:1.0; stroke:none;\n", " stroke-width:0;\">\n"] for item in self.items: var += item.strarray() var += [" </g>\n</svg>\n"] return var def write_svg(self,filename=None): if filename: self.svgname = filename else: self.svgname = self.name + ".svg" file = open(self.svgname,'w') file.writelines(self.strarray()) file.close() return def display(self,prog=display_prog): os.system("%s %s" % (prog,self.svgname)) return class Line: def __init__(self,start,end): self.start = start #xy tuple self.end = end #xy tuple return def strarray(self): return [" <line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" />\n" %\ (self.start[0],self.start[1],self.end[0],self.end[1])] class Circle: def __init__(self,center,radius,color): self.center = center #xy tuple self.radius = radius #xy tuple self.color = color #rgb tuple in range(0,256) return def strarray(self): return [" <circle cx=\"%d\" cy=\"%d\" r=\"%04f\"\n" %\ (self.center[0],self.center[1],self.radius), " style=\"fill:%s;\" />\n" % colorstr(self.color)] class Rectangle: def __init__(self,origin,height,width,color): self.origin = origin self.height = height self.width = width self.color = color return def strarray(self): return [" <rect x=\"%04f\" y=\"%04f\" height=\"%04f\"\n" %\ (float(self.origin[0]),float(self.origin[1]),float(self.height)), " width=\"%d\" style=\"fill:%s;\" />\n" %\ (self.width,colorstr(self.color))] class Text: def __init__(self,origin,text,size=24): self.origin = origin self.text = text self.size = size return def strarray(self): return [" <text x=\"%d\" y=\"%d\" font-size=\"%d\">\n" %\ (self.origin[0],self.origin[1],self.size), " %s\n" % self.text, " </text>\n"] def colorstr(rgb): return "#%x%x%x" % (rgb[0]/16,rgb[1]/16,rgb[2]/16) def test(): curImage = Image.open("/home/samh/input.gif") dimensions = curImage.size #print dimensions scale = 20.0 scene = Scene('test',dimensions[1]*scale,dimensions[0]*scale) paletteSize = 8.0#len(curImage.palette.palette)/len(curImage.palette.getdata()[0]) for row in range(dimensions[0]): for column in range(dimensions[1]): size = math.pow( (1 - float(curImage.getpixel((row,column)))/float(paletteSize))*2,0.5) * scale dimension = scale/float(paletteSize) * size black = (0,0,0) bottomRight = (row*scale,column*scale) scene.add(Rectangle(bottomRight,dimension/5.0,dimension/5.0,black)) scene.write_svg(filename="test.svg") scene.display(prog="inkscape") return if __name__ == '__main__': test() |