Mercurial > ift6266
comparison data_generation/transformations/pycaptcha/Captcha/Visual/Text.py @ 167:1f5937e9e530
More moves - transformations into data_generation, added "deep" folder
author | Dumitru Erhan <dumitru.erhan@gmail.com> |
---|---|
date | Fri, 26 Feb 2010 14:15:38 -0500 |
parents | pycaptcha/Captcha/Visual/Text.py@25b7c1f20949 |
children | 81f8466dc121 |
comparison
equal
deleted
inserted
replaced
166:17ae5a1a4dd1 | 167:1f5937e9e530 |
---|---|
1 """ Captcha.Visual.Text | |
2 | |
3 Text generation for visual CAPTCHAs. | |
4 """ | |
5 # | |
6 # PyCAPTCHA Package | |
7 # Copyright (C) 2004 Micah Dowty <micah@navi.cx> | |
8 # | |
9 | |
10 import random, os | |
11 from Captcha import Visual, File | |
12 import ImageFont, ImageDraw | |
13 | |
14 | |
15 class FontFactory(File.RandomFileFactory): | |
16 """Picks random fonts and/or sizes from a given list. | |
17 'sizes' can be a single size or a (min,max) tuple. | |
18 If any of the given files are directories, all *.ttf found | |
19 in that directory will be added. | |
20 """ | |
21 extensions = [".ttf", ".TTF"] | |
22 basePath = "fonts" | |
23 | |
24 # arguments variables a modifier pour mettre le chemin vers les fontes. | |
25 def __init__(self, sizes, *fileNames): | |
26 File.RandomFileFactory.__init__(self, *fileNames) | |
27 | |
28 if type(sizes) is tuple: | |
29 self.minSize = sizes[0] | |
30 self.maxSize = sizes[1] | |
31 else: | |
32 self.minSize = sizes | |
33 self.maxSize = sizes | |
34 | |
35 def pick(self): | |
36 """Returns a (fileName, size) tuple that can be passed to ImageFont.truetype()""" | |
37 fileName = File.RandomFileFactory.pick(self) | |
38 size = int(random.uniform(self.minSize, self.maxSize) + 0.5) | |
39 return (fileName, size) | |
40 | |
41 # Predefined font factories | |
42 defaultFontFactory = FontFactory(25, "allfonts") | |
43 #defaultFontFactory = FontFactory((30, 40), "vera") | |
44 | |
45 class TextLayer(Visual.Layer): | |
46 """Represents a piece of text rendered within the image. | |
47 Alignment is given such that (0,0) places the text in the | |
48 top-left corner and (1,1) places it in the bottom-left. | |
49 | |
50 The font and alignment are optional, if not specified one is | |
51 chosen randomly. If no font factory is specified, the default is used. | |
52 """ | |
53 def __init__(self, text, | |
54 alignment = None, | |
55 font = None, | |
56 fontFactory = None, | |
57 textColor = "white", | |
58 borderSize = 0, | |
59 borderColor = None, | |
60 ): | |
61 if fontFactory is None: | |
62 global defaultFontFactory | |
63 fontFactory = defaultFontFactory | |
64 | |
65 if font is None: | |
66 font = fontFactory.pick() | |
67 | |
68 if alignment is None: | |
69 alignment = (random.uniform(0,1), | |
70 random.uniform(0,1)) | |
71 | |
72 self.text = text | |
73 self.alignment = alignment | |
74 self.font = font | |
75 self.textColor = textColor | |
76 self.borderSize = borderSize | |
77 self.borderColor = borderColor | |
78 | |
79 def render(self, img): | |
80 font = ImageFont.truetype(*self.font) | |
81 textSize = font.getsize(self.text) | |
82 draw = ImageDraw.Draw(img) | |
83 | |
84 # Find the text's origin given our alignment and current image size | |
85 x = int((img.size[0] - textSize[0] - self.borderSize*2) * self.alignment[0] + 0.5) | |
86 y = int((img.size[1] - textSize[1] - self.borderSize*2) * self.alignment[1] + 0.5) | |
87 | |
88 # Draw the border if we need one. This is slow and ugly, but there doesn't | |
89 # seem to be a better way with PIL. | |
90 if self.borderSize > 0: | |
91 for bx in (-1,0,1): | |
92 for by in (-1,0,1): | |
93 if bx and by: | |
94 draw.text((x + bx * self.borderSize, | |
95 y + by * self.borderSize), | |
96 self.text, font=font, fill=self.borderColor) | |
97 | |
98 # And the text itself... | |
99 draw.text((x,y), self.text, font=font, fill=self.textColor) | |
100 | |
101 ### The End ### |