Example #1
0
    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)
Example #2
0
    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()
Example #5
0
 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)
Example #6
0
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
Example #7
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()
Example #8
0
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)
Example #9
0
	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
Example #10
0
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)
Example #11
0
    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()
Example #12
0
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)
Example #14
0
 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)
Example #15
0
    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")
Example #16
0
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')
Example #17
0
    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")
Example #19
0
    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