Mercurial > ift6266
annotate data_generation/transformations/pycaptcha/Captcha/Visual/Text.py @ 338:fca22114bb23
added async save, restart from old model and independant error calculation based on Arnaud's iterator
author | xaviermuller |
---|---|
date | Sat, 17 Apr 2010 12:42:48 -0400 |
parents | 81f8466dc121 |
children |
rev | line source |
---|---|
87 | 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 """ | |
132
25b7c1f20949
Adapted pycaptcha to get fonts in /Tmp/allfonts local folder
boulanni <nicolas_boulanger@hotmail.com>
parents:
87
diff
changeset
|
21 extensions = [".ttf", ".TTF"] |
87 | 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 | |
184
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
42 defaultFontFactory = FontFactory(25, "/Tmp/allfonts") |
87 | 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): | |
184
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
80 |
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
81 i=1 |
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
82 while True: |
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
83 try: |
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
84 font = ImageFont.truetype(*self.font) |
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
85 break |
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
86 except: |
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
87 print "try#", i, self.font |
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
88 i += 1 |
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
89 if i>10: raise |
81f8466dc121
Transient exception handling in captchas (ie. lorsque le NFS est temporairement inaccessible)
boulanni <nicolas_boulanger@hotmail.com>
parents:
167
diff
changeset
|
90 |
87 | 91 textSize = font.getsize(self.text) |
92 draw = ImageDraw.Draw(img) | |
93 | |
94 # Find the text's origin given our alignment and current image size | |
95 x = int((img.size[0] - textSize[0] - self.borderSize*2) * self.alignment[0] + 0.5) | |
96 y = int((img.size[1] - textSize[1] - self.borderSize*2) * self.alignment[1] + 0.5) | |
97 | |
98 # Draw the border if we need one. This is slow and ugly, but there doesn't | |
99 # seem to be a better way with PIL. | |
100 if self.borderSize > 0: | |
101 for bx in (-1,0,1): | |
102 for by in (-1,0,1): | |
103 if bx and by: | |
104 draw.text((x + bx * self.borderSize, | |
105 y + by * self.borderSize), | |
106 self.text, font=font, fill=self.borderColor) | |
107 | |
108 # And the text itself... | |
109 draw.text((x,y), self.text, font=font, fill=self.textColor) | |
110 | |
111 ### The End ### |