from PIL import Image, ImageDraw, ImageOps import math class Pipe: def __init__(self, **params): self.pos = (params.get("posX",0), params.get("posY",0)) self.size = params.get("size",100) self.resolution = params.get("resolution",300) def draw(self, im): draw = ImageDraw.Draw(im) offset = (0,-self.size) draw.arc(((self.pos[0]+offset[0])*self.resolution, (self.pos[1]+offset[1])*self.resolution, (self.pos[0]+self.size+offset[0])*self.resolution, (self.pos[1]+self.size+offset[1])*self.resolution), start=0, end=180, fill=255, width=2) class Series: def __init__(self, **params): self.name = params.get("name", "out") self.pos = (params.get("posX",0), params.get("posY",0)) self.size = params.get("size",100) self.resolution = params.get("resolution",300) self.x_dpi = self.resolution * 25.4 self.y_dpi = self.resolution * 25.4 self.stepSize = params.get("stepSize",30) self.tilt = params.get("tilt",20) self.spacer = params.get("spacer",20) self.sequence = params.get("sequence",(3,2,1,0)) def draw(self, im): draw = ImageDraw.Draw(im) idx = 0 end = (0,0) prevEnd = (self.pos[0]-self.spacer, self.pos[1]-self.sequence[0]*self.tilt-self.size/2) for height in self.sequence: tiltBios = height*self.tilt stepBios = idx*self.stepSize idxBios = idx*self.size spacerBios = idx*self.spacer pipe = Pipe(posX=self.pos[0]+idxBios+spacerBios+self.spacer, posY=self.pos[1]-tiltBios-stepBios, size=self.size, resolution=self.resolution) pipe.draw(im) end = (pipe.pos[0]+pipe.size, pipe.pos[1]-pipe.size/2) if prevEnd[1] < end[1]: shape = [(end[0]*self.resolution,end[1]*self.resolution), ((end[0]+self.spacer)*self.resolution, end[1]*self.resolution)] draw.line(shape, fill =255, width = 2) shape = [((prevEnd[0]+self.spacer)*self.resolution,prevEnd[1]*self.resolution), ((end[0]-pipe.size)*self.resolution,end[1]*self.resolution)] draw.line(shape, fill =255, width = 2) else: shape = [((prevEnd[0])*self.resolution,prevEnd[1]*self.resolution), ((prevEnd[0])*self.resolution,end[1]*self.resolution)] draw.line(shape, fill =255, width = 2) shape = [((prevEnd[0])*self.resolution,end[1]*self.resolution), ((end[0]-pipe.size)*self.resolution, end[1]*self.resolution)] draw.line(shape, fill =255, width = 2) prevEnd = end idx+=1 shape = [(self.pos[0]*self.resolution,(self.pos[1]+10)*self.resolution), ((end[0]+self.spacer)*self.resolution, (self.pos[1]+10)*self.resolution)] draw.line(shape, fill =255, width = 2) shape = [((end[0])*self.resolution, end[1]*self.resolution), ((end[0]+self.spacer)*self.resolution, end[1]*self.resolution)] draw.line(shape, fill =255, width = 2) shape = [((end[0]+self.spacer)*self.resolution,(self.pos[1]+10)*self.resolution), ((end[0]+self.spacer)*self.resolution, end[1]*self.resolution)] draw.line(shape, fill =255, width = 2) shape = [(self.pos[0]*self.resolution,(self.pos[1]+10)*self.resolution), (self.pos[0]*self.resolution, (self.pos[1]-self.sequence[0]*self.tilt-self.size/2)*self.resolution)] draw.line(shape, fill =255, width = 2) def cropNsave(self, im, imSize, tileSize=(180, 280)): numTilesX = math.ceil((imSize[0] / self.resolution) / tileSize[0]) numTilesY = math.ceil((imSize[1] / self.resolution) / tileSize[1]) for y in range(0,numTilesY): for x in range(0,numTilesX): x0=x*tileSize[0]*self.resolution y0=y*tileSize[1]*self.resolution x1=x0+tileSize[0]*self.resolution y1=y0+tileSize[1]*self.resolution subIm = im.crop((x0, y0, x1, y1)) self.drawMarker(subIm, tileSize) ImageOps.invert(subIm).save("%s-%s-%s.png"%(self.name,x,y), dpi=(self.x_dpi, self.y_dpi)) def drawMarker(self, subIm, tileSize): x0 = 0 y0 = 0 x1 = tileSize[0]*self.resolution y1 = tileSize[1]*self.resolution length = 40 draw = ImageDraw.Draw(subIm) shapes = [ [(x0,y0), (x0+length,y0)], [(x0,y0), (x0,y0+length)], [(x0,y1), (x0+length,y1)], [(x0,y1), (x0,y1-length)], [(x1,y0), (x1-length,y0)], [(x1,y0), (x1,y0+length)], [(x1,y1), (x1-length,y1)], [(x1,y1), (x1,y1-length)] ] for shape in shapes: draw.line(shape, fill =200, width = 20) def main(): imSize = (7000, 5599) resolution = 10 im = Image.new('L', imSize, 0) aSide = Series(name="aSide", posX=10, posY=300, sequence=(0,2,2,4,4), resolution=resolution, size=110) aSide.draw(im) ImageOps.invert(im).save("aSide.png", dpi=(aSide.x_dpi, aSide.y_dpi)) aSide.cropNsave(im, imSize) im = Image.new('L', imSize, 0) bSide = Series(name="bSide",posX=10, posY=300, sequence=(1,1,3,3,5), resolution=resolution, size=110) bSide.draw(im) ImageOps.invert(im).save("bSide.png", dpi=(bSide.x_dpi, bSide.y_dpi)) bSide.cropNsave(im, imSize) main()