Commits

Andriy Kornatskyy  committed d4e79b0

Added bezier curve drawer.

  • Participants
  • Parent commits 331150a

Comments (0)

Files changed (5)

File demos/app.py

 from wheezy.captcha.image import captcha
 
 from wheezy.captcha.image import background
+from wheezy.captcha.image import curve
 from wheezy.captcha.image import noise
 from wheezy.captcha.image import smooth
 from wheezy.captcha.image import text
             rotate(),
             offset()
         ]),
+    curve(),
     noise(),
     smooth()
 ])

File demos/sample.py

 from wheezy.captcha.image import captcha
 
 from wheezy.captcha.image import background
+from wheezy.captcha.image import curve
 from wheezy.captcha.image import noise
 from wheezy.captcha.image import smooth
 from wheezy.captcha.image import text
             drawings=[
                 warp(),
                 rotate(),
-                offset()]),
+                offset()
+            ]),
+        curve(),
         noise(),
         smooth()
     ])

File sample.jpg

Old
Old image
New
New image

File src/wheezy/captcha/bezier.py

+
+"""
+"""
+
+
+tsequence = tuple([t / 20.0 for t in range(21)])
+beziers = {}
+
+
+def pascal_row(n):
+    """ Returns n-th row of Pascal's triangle
+    """
+    result = [1]
+    x, numerator = 1, n
+    for denominator in range(1, n // 2 + 1):
+        x *= numerator
+        x /= denominator
+        result.append(x)
+        numerator -= 1
+    if n & 1 == 0:
+        result.extend(reversed(result[:-1]))
+    else:
+        result.extend(reversed(result))
+    return result
+
+
+def make_bezier(n):
+    """ Bezier curves:
+        http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Generalization
+    """
+    try:
+        return beziers[n]
+    except KeyError:
+        combinations = pascal_row(n - 1)
+        result = []
+        for t in tsequence:
+            tpowers = (t ** i for i in range(n))
+            upowers = ((1 - t) ** i for i in range(n - 1, -1, -1))
+            coefs = [c * a * b for c, a, b in zip(combinations,
+                                                  tpowers, upowers)]
+            result.append(coefs)
+        beziers[n] = result
+        return result

File src/wheezy/captcha/image.py

     return drawer
 
 
+def curve(color='#5C87B2', width=4, number=6):
+    from wheezy.captcha.bezier import make_bezier
+    if not callable(color):
+        c = getrgb(color)
+        color = lambda: c
+
+    def drawer(image, text):
+        dx, height = image.size
+        dx = dx / number
+        path = [(dx * i, random.randint(0, height))
+                for i in range(1, number)]
+        bcoefs = make_bezier(number - 1)
+        points = []
+        for coefs in bcoefs:
+            points.append(tuple(sum([coef * p for coef, p in zip(coefs, ps)])
+                          for ps in zip(*path)))
+        draw = Draw(image)
+        draw.line(points, fill=color(), width=width)
+        return image
+    return drawer
+
+
 def noise(number=50, color='#EEEECC', level=2):
     if not callable(color):
         c = getrgb(color)
             drawings=[
                 warp(),
                 rotate(),
-                offset()]),
+                offset()
+            ]),
+        curve(),
         noise(),
         smooth()
     ])