def drawString(self, s, x, y, font=None, color=None, angle=0, **kwargs): "Draw a string starting at location x,y." x = int(x) y = int(y) if '\n' in s or '\r' in s: self.drawMultiLineString(s, x, y, font, color, angle, **kwargs) return if not font: font = self.defaultFont if not color: color = self.defaultLineColor if color == transparent: return # draw into an offscreen Image # tmpsize was originally 1.2* stringWidth, added code to give enough room for single character strings (piddle bug#121995) sHeight = (self.fontAscent(font) + self.fontDescent(font)) sWidth = self.stringWidth(s, font) tempsize = max(sWidth * 1.2, sHeight * 2.0) tempimg = Image.new('RGB', (int(tempsize), int(tempsize)), (0, 0, 0)) temppen = ImageDraw.ImageDraw(tempimg) pilfont = _pilFont(font) if not pilfont: raise ValueError("bad font: %s" % font) pos = [ 4, int(tempsize / 2 - self.fontAscent(font)) - self.fontDescent(font) ] temppen.text(pos, s, font=pilfont, fill=(255, 255, 255)) pos[1] = int(tempsize / 2) if font.underline: ydown = (0.5 * self.fontDescent(font)) # thickness = 0.08 * font.size # may need to ceil this temppen.line( (pos[0], pos[1] + ydown, pos[0] + sWidth, pos[1] + ydown)) # rotate if angle: from math import pi, sin, cos tempimg = tempimg.rotate(angle, Image.BILINEAR) temppen = ImageDraw.ImageDraw(tempimg) radians = -angle * pi / 180.0 r = tempsize / 2 - pos[0] pos[0] = int(tempsize / 2 - r * cos(radians)) pos[1] = int(pos[1] - r * sin(radians)) # temppen.rectangle( (pos[0],pos[1],pos[0]+2,pos[1]+2) ) # PATCH for debugging # colorize, and copy it in mask = tempimg.convert('L').point(lambda c: c) clr = (int(color.red * 255), int(color.green * 255), int(color.blue * 255)) temppen.rectangle((0, 0, tempsize, tempsize), fill=clr) self._image.paste(tempimg, (int(x) - pos[0], int(y) - pos[1]), mask)
def augment(self, args, video, data, frames): offset = 100 for im, frame in frames: aug = Image.new(im.mode, (im.size[0], im.size[1] + offset)) aug.paste("black") aug.paste(im, (0, 0)) draw = ImageDraw.ImageDraw(aug) s = im.size[1] font = ImageFont.truetype("arial.ttf", 14) # extract some data workerids = set() sum = 0 for track in data: if frame in (x.frame for x in track.boxes): for worker in track.workers: if worker not in workerids and worker is not None: workerids.add(worker) sum += 1 ypos = s + 5 for worker in workerids: draw.text((5, ypos), worker, fill="white", font=font) ypos += draw.textsize(worker, font=font)[1] + 3 size = draw.textsize(video.slug, font=font) draw.text((im.size[0] - size[0] - 5, s + 5), video.slug, font=font) text = "{0} annotations".format(sum) numsize = draw.textsize(text, font=font) draw.text((im.size[0] - numsize[0] - 5, s + 5 + size[1] + 3), text, font=font) yield aug, frame
def waterMark(text): main = Image.open("images/nike.jpg") watermark = Image.new("RGBA", main.size) #print im.format, im.size, im.mode # Create a new image for the watermark with an alpha layer (RGBA) # the same size as the original image watermark = Image.new("RGBA", main.size) # Get an ImageDraw object so we can draw on the image waterdraw = ImageDraw.ImageDraw(watermark, "RGBA") # Place the text at (10, 10) in the upper left corner. Text will be white. waterdraw.text((100, 120), text) # Get the watermark image as grayscale and fade the image # See <http://www.pythonware.com/library/pil/handbook/image.htm#Image.point> # for information on the point() function # Note that the second parameter we give to the min function determines # how faded the image will be. That number is in the range [0, 256], # where 0 is black and 256 is white. A good value for fading our white # text is in the range [100, 200]. watermask = watermark.convert("L").point(lambda x: min(x, 200)) # Apply this mask to the watermark image, using the alpha filter to # make it transparent watermark.putalpha(watermask) # Paste the watermark (with alpha layer) onto the original image and save it main.paste(watermark, None, watermark) main.save("images/watermarked/nike-watermarked.jpg", "JPEG")
def dibuja_grafo(self, estado=None): """ Dibuja el grafo utilizando PIL, donde estado es una lista de dimensión 2*len(vertices), donde cada valor es la posición en x y y respectivamente de cada vertice. dim es la dimensión de la figura en pixeles. Si no existe una posición, entonces se obtiene una en forma aleatoria. """ if not estado: estado = self.estado_aleatorio() # Diccionario donde lugar[vertice] = (posX, posY) lugar = self.estado2dic(estado) # Abre una imagen y para dibujar en la imagen # Imagen en blanco imagen = Image.new('RGB', (self.dim, self.dim), (255, 255, 255)) dibujar = ImageDraw.ImageDraw(imagen) for (v1, v2) in self.aristas: dibujar.line((lugar[v1], lugar[v2]), fill=(255, 0, 0)) for v in self.vertices: dibujar.text(lugar[v], v, (0, 0, 0)) imagen.show()
def __init__(self, size=(300, 300), name='piddlePIL'): self._image = Image.new('RGB', size, (255, 255, 255)) import ImageDraw self._pen = ImageDraw.ImageDraw(self._image) self._pen.setink(0) self._setFont(Font()) self._pilversion = map(string.atoi, string.split(Image.VERSION, ".")) Canvas.__init__(self, size, name)
def add_num(img): draw = ImageDraw(img) myfont = ImageFont.truetype('/Library/Fonts/Arial Italic.ttf ', size=40) fillcolor = "#ff0000" width, height = img.size draw.text((width - 40, 0), '99', font=myfont, fill=fillcolor) img.save('result.jpg', 'jpeg') return 0
def dibuja_grafo(self, estado=None): """ Dibuja el grafo utilizando PIL, donde estado es una lista de dimensión 2*len(vertices), donde cada valor es la posición en x y y respectivamente de cada vertice. dim es la dimensión de la figura en pixeles. Si no existe una posición, entonces se obtiene una en forma aleatoria. """ if not estado: estado = self.estado_aleatorio() # Diccionario donde lugar[vertice] = (posX, posY) lugar = self.estado2dic(estado) # Abre una imagen y para dibujar en la imagen imagen = Image.new('RGB', (self.dim, self.dim), (255, 255, 255)) # Imagen en blanco dibujar = ImageDraw.ImageDraw(imagen) for (v1, v2) in self.aristas: dibujar.line((lugar[v1], lugar[v2]), fill=(255, 0, 0)) for v in self.vertices: dibujar.text(lugar[v], v, (0, 0, 0)) """ # Metodo rebuscado para nombrar los archivos. Toda la mugre que prosigue # es sustituible por "imagen.show()", funcion que a mi no me funciona # Tengo un archivo "numbering" guardado en "fpath" que inicialmente tiene # escrito un numero (0 o 1, al gusto) (sin saltos de linea) # Cada vez que guarda un archivo le 'appenda' el numero al final, y aumenta # el numero del archivo en 1. def get_number(): fpath = r"C:\Users\ManueelVR\Desktop\7mo Semstre\Inteligencia Artificial\Tarea2 - busquedas locales\numbering" f = open(fpath, 'r') fnum_corrida = f.read() f.close() f = open(fpath, 'w') f.write(str(int(fnum_corrida)+1)) f.close() return fnum_corrida fname = "prueba-" fname += get_number() fname += ".jpg" print "Guardando archivo " + fname imagen.save(fname) """ imagen.show()
def draw_text(text, size=12): ink = eink.Eink() font = ImageFont.truetype('DejaVuSerif.ttf', size) # generate images img = ink.new() d = ImageDraw.ImageDraw(img) width, height = d.multiline_textsize(text, font) d.multiline_text(((img.width - width)/2, (img.height - height)/2), text, eink.BLACK, font) # display images ink.display(img)
def __init__(self, width, height, search_resolution): self.rect_list = [] self.packed_rect_list = [] self.search_step = 0 self.area_covered = 0 self.width = width self.height = height self.image = Image.new("RGBA", (width, height)) self.draw = ImageDraw.ImageDraw(self.image) self.search_resolution = search_resolution
def draw_text(text, size=12): ink = eink.Eink() font = ImageFont.truetype('DejaVuSansMono.ttf', size) # generate images img = ink.new() d = ImageDraw.ImageDraw(img) text_black, text_red = parse(text) width, height = d.multiline_textsize(text_black, font) pos = (img.width - width) / 2, (img.height - height) / 2 d.multiline_text(pos, text_black, eink.BLACK, font) d.multiline_text(pos, text_red, eink.RED, font) # display images ink.display(img)
def createDisplay(self): self.width = self.root.winfo_width() - 10 self.height = self.root.winfo_height() - 95 self.form = self.createcomponent('form', (), None, Frame, (self.interior(), ), width=self.width, height=self.height) self.form.pack(side=TOP, expand=YES, fill=BOTH) self.im = Image.new("P", (self.width, self.height), 0) self.d = ImageDraw.ImageDraw(self.im) self.d.setfill(0) self.label = self.createcomponent( 'label', (), None, Label, (self.form, ), ) self.label.pack()
def watermark_use_text(im, text, outfile, pos_x=0, pos_y=0, fonttype="", fontsize=60, fontcolor=(0, 0, 0)): if not hasattr(im, 'getim'): # a PIL Image object raise NotIsPilObject watermark = Image.new("RGBA", (im.size[0], im.size[1])) draw = ImageDraw.ImageDraw(watermark, "RGBA") font = ImageFont.truetype(fonttype, fontsize) if fontcolor: draw.text((pos_x, pos_y), text, font=font, fill=fontcolor) else: draw.text((pos_x, pos_y), text, font=font) im.paste(watermark, None, watermark) im.save(outfile)
ttfont = ImageFont.truetype(path, 30) print path while (length > 0): choice = random.randint(0, seed - 1) print letters[choice] string = string + letters[choice] length = length - len(letters[choice]) r = random.randint(0, 255) g = random.randint(0, 255) b = random.randint(0, 255) watermark = Image.new("RGBA", im.size) waterdraw = ImageDraw.ImageDraw(watermark, "RGBA") waterdraw.text((12, 12), string, fill=(255, 255, 255), font=ttfont) t_width, t_height = waterdraw.textsize(unicode(string, 'UTF-8'), font = ttfont) #print r #print g #print b print string #box = (0, 0, 20 + t_width, 30 + t_height) rX = 16 + t_width rY = 27 + t_height box = (8, 12, rX, rY)
def __init__(self, size=(300, 300), name='piddlePIL'): self._image = Image.new('RGB', (int(size[0]), int(size[1])), (255, 255, 255)) self._pen = ImageDraw.ImageDraw(self._image) self._setFont(Font()) Canvas.__init__(self, size, name)
def drawTrack(self, filename=''): global verbose if verbose: print 'GPX.drawTrack()' if filename == '' or filename == None: filename = self.options.get('filename') if filename == '' or filename == None: trackFile, trackType = os.path.splitext(self.trackname) filename = trackFile + '.png' imagesize = (self.tiles['x']['count'] * 256, self.tiles['y']['count'] * 256) image = Image.new("RGB", imagesize, '#ffffff') # If user wants OSM tile background, do it # TODO without OSM tiles, our current code wont crop the track well if self.options.get('background'): cachelocation = os.path.join('.', self.options.get('cache'), self.options.get('renderer')) image = Tile.populateBackground(self.options.get('tileserver'), cachelocation, self.tiles, image) # compute pixel locations pointlist = map( lambda x: Tile.getPixelForCoord(x, self.tilesbounds, imagesize), self.points) # TODO give user option to style # XXX Supersample our line to make it smarter if self.options.get('antialiased'): newsize = (imagesize[0] * 4, imagesize[1] * 4) background = image.resize(newsize) draw = ImageDraw.ImageDraw(background) pointlist = map( lambda x: Tile.getPixelForCoord(x, self.tilesbounds, newsize), self.points) draw.line(pointlist, fill=self.options.get('linecolour'), width=self.options.get('linewidth') * 4) image = background.resize(imagesize, Image.ANTIALIAS) else: draw = ImageDraw.Draw(image) pointlist = map( lambda x: Tile.getPixelForCoord(x, self.tilesbounds, imagesize ), self.points) draw.line(pointlist, fill=self.options.get('linecolour'), width=self.options.get('linewidth')) # Attempt to intelligently trim the image if its over # TODO give user a gutter option # TODO give user a scale option # TODO move to function size = self.options.get('size') if size * size < self.tiles['x']['count'] * self.tiles['y']['count']: path = [ Tile.getPixelForCoord(self.pointsbounds[0], self.tilesbounds, imagesize), Tile.getPixelForCoord(self.pointsbounds[1], self.tilesbounds, imagesize) ] imagebox = [[0, 0], list(imagesize)] # so here we have a bounding box for the path, can we trim edges of image? if imagesize[0] > size * 256: # TODO assumption is, we can trim a tile, might need 2 × in future if path[1][0] - path[0][0] < imagesize[0] - 256: # We can trim centrex = (path[1][0] - path[0][0]) / 2 + path[0][0] halfwidth = ((imagesize[0] - 256) / 2) imagebox[0][0] = centrex - halfwidth imagebox[1][0] = centrex + halfwidth if imagesize[1] > size * 256: # TODO same as above if path[1][1] - path[0][1] < imagesize[1] - 256: centrey = (path[1][1] - path[0][1]) / 2 + path[0][1] halfwidth = ((imagesize[1] - 256) / 2) imagebox[0][1] = centrey - halfwidth imagebox[1][1] = centrey + halfwidth imagebox = reduce(lambda x, y: x + y, imagebox) image = image.crop(imagebox) #trim = int(256/2) #image = image.crop( tuple( [trim, trim] + map( lambda x: x-trim, image.size) ) ) # Only draw if OSM background used. if self.options.get('background'): # Draw CC licence image ccimage = 'cc-by-sa.' + self.options.get('notice') + '.png' # TODO fail if image is missing cclogo = Image.open(ccimage) cclocation = { 'small': (85, 20), # small 80 × 15 'normal': (93, 36), # normal 88 × 31 }.get(self.options.get('notice'), (85, 20)) cclocation = (image.size[0] - cclocation[0], image.size[1] - cclocation[1]) image.paste(cclogo, cclocation, cclogo) # Draw OSM logo osmlogo = Image.open('osm.png') osmlogosize = { 'small': 16, # small 80 × 15 'normal': 32, # normal 88 × 31 }.get(self.options.get('notice'), 32) osmlogo = osmlogo.resize((osmlogosize, osmlogosize), Image.ANTIALIAS) osmlocation = (cclocation[0] - osmlogosize - 5, cclocation[1]) image.paste(osmlogo, osmlocation, osmlogo) # write file image.save(filename, "PNG")
def drawText(dic, split_str, index, prs, mode="n", debug=False): ttfont = prs.font image_path = prs.image_path outputFilePath = prs.outputFilePath im = Image.open(image_path).convert('RGB') r = random.randint(0, 255) g = random.randint(0, 255) b = random.randint(0, 255) filename = "" draw = ImageDraw.Draw(im) if split_str == "": print tc.UseStyle("[ERROR] string is empty.", fore='red') return filename if not isinstance(index, list) or len(index) != 1 or not isinstance( index[0], int): print tc.UseStyle("[ERROR] index type of length is invalid.", fore='red') return filename if debug == True: print tc.UseStyle("mode=%s, new text=%s, color of it = (%s, %s, %s)" % (mode, split_str, r, g, b), fore='green') if mode == "n": try: draw.text((12, 14), split_str.decode('utf-8'), fill=(r, g, b), font=ttfont) t_width, t_height = draw.textsize(unicode(split_str, 'utf-8'), font=ttfont) rX = 16 + t_width rY = 24 + t_height box = (8, 12, rX, rY) alpha = random.randint(20, 160) except: import chardet print tc.UseStyle("[ERROR]:original string:%s, coding:%s" % (split_str, chardet.detect(split_str)), fore='red') return filename if mode == "v": try: draw.text((50, 50), split_str.decode('utf-8'), fill=(r, g, b), font=ttfont) t_width, t_height = draw.textsize(unicode(split_str, 'utf-8'), font=ttfont) rX = 58 + t_width rY = 67 + t_height vwidth = random.randint(-10, 10) vheight = random.randint(-10, 10) box = (39 + vwidth, 40 + vheight, rX + vwidth, rY + vheight) except: import chardet print tc.UseStyle("[ERROR]:original string:%s, coding:%s" % (split_str, chardet.detect(split_str)), fore='red') return filename if mode == "w": try: watermark = Image.new("RGBA", im.size) draw = ImageDraw.ImageDraw(watermark, "RGBA") draw.text((12, 12), split_str.decode('utf-8'), fill=(r, g, b), font=ttfont) t_width, t_height = draw.textsize(unicode(split_str, 'utf-8'), font=ttfont) rX = 16 + t_width rY = 24 + t_height box = (8, 12, rX, rY) alpha = random.randint(20, 160) watermask = watermark.convert("L").point(lambda x: min(x, alpha)) watermark.putalpha(watermask) im.paste(watermark, None, watermark) except: import chardet print tc.UseStyle("[ERROR]:original string:%s, coding:%s" % (split_str, chardet.detect(split_str)), fore='red') return filename region = im.crop(box) filename = 'image-' + str(index[0]) + '-' + str(int( time.time())) + '-' + prs.font_name + '.jpg' region.save(outputFilePath + "/" + filename) index[0] = index[0] + 1 try: flag, conv = stringDicCoding(dic, split_str) if not flag: print tc.UseStyle("[ERROR]:dictionary is empty.", fore='red') return filename prs.csvfile.write('%s%s%s\n' % (filename, conv, split_str.decode('utf-8'))) except Exception, e: print repr(e) import chardet print tc.UseStyle("[ERROR]:csvfile riginal string:%s, coding:%s" % (split_str, chardet.detect(split_str)), fore='red')
def _drawRotatedString(self, s, x,y, font=None, color=None, angle=0): try: import p4vasp.piddle.piddlePIL as piddlePIL import Image, ImageTk pp = piddlePIL except ImportError: raise ImportError("Rotated strings only possible with PIL support") pilCan = pp.PILCanvas(size=(self.width,self.height)) pilCan.defaultFont = self.defaultFont pilCan.defaultLineColor = self.defaultLineColor if '\n' in s or '\r' in s: self.drawMultiLineString(s, x,y, font, color, angle) return if not font: font = pilCan.defaultFont if not color: color = self.defaultLineColor if color == piddle.transparent: return # draw into an offscreen Image tempsize = pilCan.stringWidth(s, font) * 1.2 tempimg = Image.new('RGB',(tempsize,tempsize), (0,0,0)) txtimg = Image.new('RGB',(tempsize,tempsize), (255,255,255)) import ImageDraw temppen = ImageDraw.ImageDraw(tempimg) temppen.setink( (255,255,255) ) pilfont = pp._pilFont(font) if not pilfont: raise "bad font!", font temppen.setfont( pilfont ) pos = [4, int(tempsize/2 - pilCan.fontAscent(font)) - pilCan.fontDescent(font)] temppen.text( pos, s ) pos[1] = int(tempsize/2) # rotate if angle: from math import pi, sin, cos tempimg = tempimg.rotate( angle, Image.BILINEAR ) temppen = ImageDraw.ImageDraw(tempimg) radians = -angle * pi/180.0 r = tempsize/2 - pos[0] pos[0] = int(tempsize/2 - r * cos(radians)) pos[1] = int(pos[1] - r * sin(radians)) ###temppen.rectangle( (pos[0],pos[1],pos[0]+2,pos[1]+2) ) # PATCH for debugging # colorize, and copy it in mask = tempimg.convert('L').point(lambda c:c) temppen.setink( (color.red*255, color.green*255, color.blue*255) ) temppen.setfill(1) temppen.rectangle( (0,0,tempsize,tempsize) ) txtimg.paste( tempimg, (0,0), mask) ##Based on code posted by John Michelson in the PIL SIG transp = txtimg.convert("RGBA") source = transp.split() R, G, B, A = 0, 1, 2, 3 mask = transp.point(lambda i: i < 255 and 255) # use white as transparent source[A].paste(mask) transp = Image.merge(transp.mode, source) # build a new multiband image self.drawImage(transp, x-pos[0], y-pos[1])
def get_crossword_image_grid(self, output, solved=False): """Draw an image""" ppb = self.ppb num_offset = 2 shadow_depth= ppb*0.25 font = ImageFont.truetype("/usr/share/fonts/TTF/arial.ttf", int(ppb/1.5)) number_font = ImageFont.truetype("/usr/share/fonts/TTF/arial.ttf", int(ppb/3)) if self.solution: width, height = self.crossword.cols*ppb, self.crossword.rows*ppb height += 2*ppb if len(self.solution)*ppb > width: width = len(self.solution)*ppb else: width, height = self.crossword.cols*ppb, self.crossword.rows*ppb img = Image.new("RGBA", (width, height), self.colors["bg"]) draw = ImageDraw.ImageDraw(img) #~ draw.rectangle([(0, 0), (self.crossword.rows*self.ppb, self.crossword.cols*self.ppb)], fill="white") ## Solution-box coords: if self.solution: solution_len = len(self.solution)*ppb start_x = width/2 - solution_len/2 start_y = height - ppb #~ solution_coords = [(x, start_y) for x in xrange(start_x, start_x+solution_len, ppb)] #~ solution_coords = [(x, start_y//ppb) for x in xrange(start_x//ppb, (start_x//ppb)+(solution_len//ppb))] c = 0 solution_coords = [] for letter in self.solution: #~ for x in xrange(start_x//ppb, (start_x//ppb)+(solution_len//ppb)): if letter == " ": solution_coords.append((None, None)) else: solution_coords.append((start_x//ppb + c, start_y//ppb)) c += 1 ## --------- ## Draw shadow ppb = self.ppb for letter in self.crossword.letters: for col, row in self.crossword.letters[letter]: col -= 1 row -= 1 draw.polygon([col*ppb,row*ppb, col*ppb+shadow_depth, row*ppb-shadow_depth, (col+1)*ppb+shadow_depth, row*ppb-shadow_depth, (col+1)*ppb+shadow_depth, (row+1)*ppb-shadow_depth, (col+1)*ppb, (row+1)*ppb, col*ppb, (row+1)*ppb, col*ppb, row*ppb], fill=self.colors["shadow-grid"], outline=self.colors["shadow-grid"]) #~ draw.rectangle([col*self.ppb, row*self.ppb-3, (col+1)*self.ppb+3, (row+1)*self.ppb], fill=self.colors["shadow-grid"], outline=self.colors["shadow-grid"]) if self.solution: for col, row in solution_coords: if col and row: col -= 1 row -= 1 draw.polygon([col*ppb,row*ppb, col*ppb+shadow_depth, row*ppb-shadow_depth, (col+1)*ppb+shadow_depth, row*ppb-shadow_depth, (col+1)*ppb+shadow_depth, (row+1)*ppb-shadow_depth, (col+1)*ppb, (row+1)*ppb, col*ppb, (row+1)*ppb, col*ppb, row*ppb], fill=self.colors["shadow-grid"], outline=self.colors["shadow-grid"]) ## --------- ## Draw grid for col in range(self.crossword.cols): row = 0 for cell in self.crossword.grid[col]: if not cell == self.crossword.empty: if (col+1, row+1) in self.solution_letters: fill_color = self.highlight_colors[self.solution_letters[(col+1, row+1)]] #self.colors["highlight"] else: fill_color = self.colors["bg-box"] draw.rectangle([col*self.ppb, row*self.ppb, (col+1)*self.ppb, (row+1)*self.ppb], outline=self.colors["grid"], fill=fill_color) row += 1 if self.solution: highlight_color = 0 for col, row in solution_coords: if col and row: col -= 1 row -= 1 fill_color = self.highlight_colors[highlight_color] draw.rectangle([col*self.ppb, row*self.ppb, (col+1)*self.ppb, (row+1)*self.ppb], outline=self.colors["grid"], fill=fill_color) else: highlight_color += 1 ## --------- ## Draw numbers and letters self.blocked_fields = [] for word in self.crossword.placed_words: col, row = word.col, word.row if solved: letter_counter = 0 for letter in word.word: w, h = draw.textsize(letter, font=font) letter_offset_x = self.ppb/2 - w/2 letter_offset_y = self.ppb/2 - h/2 if word.vertical: draw.text(((col-1)*self.ppb+letter_offset_x, (row-1+letter_counter)*self.ppb+letter_offset_y), str(letter), fill="black", font=font) else: draw.text(((col-1+letter_counter)*self.ppb+letter_offset_x, (row-1)*self.ppb+letter_offset_y), str(letter), fill="black", font=font) letter_counter+=1 if (col, row) in self.blocked_fields: dummy, y_offset = draw.textsize("123456789", font=number_font) else: y_offset = 0 draw.text(((col-1)*self.ppb+num_offset, (row-1)*self.ppb+num_offset+y_offset), str(word.number), fill=self.colors["text"], font=number_font) w, h = draw.textsize(str(word.number), font=number_font) #~ w = w/len(str(word.number)) if word.vertical: self._draw_arrow(draw, "down", (col-1)*self.ppb+num_offset+w, (row-1)*self.ppb+num_offset+y_offset, w/len(str(word.number)), h) else: self._draw_arrow(draw, "right", (col-1)*self.ppb+num_offset+w, (row-1)*self.ppb+num_offset+y_offset, w/len(str(word.number)), h) self.blocked_fields.append((col, row)) ## ---------- ## Draw Solution if solved and self.solution: for letter in self.solution[::-1]: w, h = draw.textsize(letter, font=font) letter_offset_x = self.ppb/2 - w/2 letter_offset_y = self.ppb/2 - h/2 col, row = solution_coords.pop() if col and row: draw.text(((col-1)*self.ppb+letter_offset_x, (row-1)*self.ppb+letter_offset_y), letter, fill="black", font=font) img.save(output, "PNG")
def renderArea(self, width_, height_, srs, xmin_, ymin_, xmax_, ymax_, zoom): """ """ merc = Proj(srs) # use the center to figure out our UTM zone lon, lat = merc((xmin_ + xmax_)/2, (ymin_ + ymax_)/2, inverse=True) zone = lon2zone(lon) hemi = lat2hemi(lat) utm = Proj(proj='utm', zone=zone, datum='WGS84') # get to UTM coords (minlon, minlat), (maxlon, maxlat) = merc(xmin_, ymin_, inverse=1), merc(xmax_, ymax_, inverse=1) (xmin, ymin), (xmax, ymax) = utm(minlon, minlat), utm(maxlon, maxlat) # figure out how widely-spaced they should be pixels = _hypot(width_, height_) # number of pixels across the image units = _hypot(xmax - xmin, ymax - ymin) # number of UTM units across the image tick = self.tick * units/pixels # desired tick length in UTM units count = pixels / self.spacing # approximate number of lines across the image bound = units / count # too-precise step between lines in UTM units zeros = int(_ceil(_log(bound) / _log(10))) # this value gets used again to format numbers step = int(_pow(10, zeros)) # a step that falls right on the 10^n # and the outer UTM bounds xbot, xtop = int(xmin - xmin % step), int(xmax - xmax % step) + 2 * step ybot, ytop = int(ymin - ymin % step), int(ymax - xmax % step) + 2 * step # start doing things in pixels img = Image.new('RGBA', (width_, height_), (0xEE, 0xEE, 0xEE, 0x00)) draw = ImageDraw.ImageDraw(img) xform = transform(width_, height_, xmin_, ymax_, xmax_, ymin_) lines = [] labels = [] for col in range(xbot, xtop, step): # set up the verticals utms = [(col, y) for y in range(ybot, ytop, step/10)] mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in utms] lines.append( [xform(x, y) for (x, y) in mercs] ) # and the tick marks for row in range(ybot, ytop, step/10): mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in ((col, row), (col - tick, row))] lines.append( [xform(x, y) for (x, y) in mercs] ) for row in range(ybot, ytop, step): # set up the horizontals utms = [(x, row) for x in range(xbot, xtop, step/10)] mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in utms] lines.append( [xform(x, y) for (x, y) in mercs] ) # and the tick marks for col in range(xbot, xtop, step/10): mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in ((col, row), (col, row - tick))] lines.append( [xform(x, y) for (x, y) in mercs] ) # set up the intersection labels for x in range(xbot, xtop, step): for y in range(ybot, ytop, step): lon, lat = utm(x, y, inverse=1) grid = lonlat2grid(lon, lat) point = xform(*merc(lon, lat)) if self.display == 'utm': e = ('%07d' % x)[:-zeros] n = ('%07d' % y)[:-zeros] text = ' '.join( [grid, e, n] ) elif self.display == 'mgrs': e, n = Proj(proj='utm', zone=lon2zone(lon), datum='WGS84')(lon, lat) text = utm2mgrs(round(e), round(n), grid, zeros) labels.append( (point, text) ) # do the drawing bits for ((x, y), text) in labels: x, y = x + 2, y - 18 w, h = self.font.getsize(text) draw.rectangle((x - 2, y, x + w + 2, y + h), fill=(0xFF, 0xFF, 0xFF, 0x99)) for line in lines: draw.line(line, fill=(0xFF, 0xFF, 0xFF)) for line in lines: draw.line([(x-1, y-1) for (x, y) in line], fill=(0x00, 0x00, 0x00)) for ((x, y), text) in labels: x, y = x + 2, y - 18 draw.text((x, y), text, fill=(0x00, 0x00, 0x00), font=self.font) return img