annotate pycaptcha/Captcha/Visual/Text.py @ 114:0b4080394f2c

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