From a2e792ba79c4d954e885d922a11912460e5b7f40 Mon Sep 17 00:00:00 2001 From: piernov Date: Sat, 28 Feb 2015 22:23:28 +0100 Subject: Replace xrange() with range() --- jm2l/captcha.py | 8 +-- jm2l/captcha.py.orig | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 jm2l/captcha.py.orig diff --git a/jm2l/captcha.py b/jm2l/captcha.py index 8ec778f..521d726 100644 --- a/jm2l/captcha.py +++ b/jm2l/captcha.py @@ -55,10 +55,10 @@ class _PyCaptcha_WarpBase(object): # Create a list of arrays with transformed points xRows = [] yRows = [] - for j in xrange(yPoints): + for j in range(yPoints): xRow = [] yRow = [] - for i in xrange(xPoints): + for i in range(xPoints): x, y = f(i*r, j*r) # Clamp the edges so we don't get black undefined areas @@ -73,8 +73,8 @@ class _PyCaptcha_WarpBase(object): # Create the mesh list, with a transformation for # each square between points on the grid mesh = [] - for j in xrange(yPoints-1): - for i in xrange(xPoints-1): + for j in range(yPoints-1): + for i in range(xPoints-1): mesh.append(( # Destination rectangle (i*r, j*r, diff --git a/jm2l/captcha.py.orig b/jm2l/captcha.py.orig new file mode 100644 index 0000000..8ec778f --- /dev/null +++ b/jm2l/captcha.py.orig @@ -0,0 +1,151 @@ +# Stolen from tgcaptcha/plugins +# http://code.google.com/p/tgcaptcha/source/browse/trunk/tgcaptcha/plugins/image/vanasco_dowty/captcha.py + +import random +from PIL import Image, ImageDraw, ImageFont, ImageFilter +from io import BytesIO +import math +from pyramid.view import view_config +from .words import TabMots +from pyramid.response import Response + +class Captcha_Img(object): + def __init__( self, width, height): + self.width = width + self.height = height + self._layers = [ + _PyCaptcha_SineWarp(amplitudeRange = (4, 8) , periodRange=(0.65,0.73) ), + ] + + def getImg(self): + """Get a PIL image representing this CAPTCHA test, creating it if necessary""" + if not self._image: + self._image = self.render() + return self._image + + def render(self): + """Render this CAPTCHA, returning a PIL image""" + size = (self.width,self.height) + #img = Image.new("RGB", size ) + img = self._image + for layer in self._layers: + img = layer.render( img ) or img + self._image = img + return self._image + +class _PyCaptcha_WarpBase(object): + """Abstract base class for image warping. Subclasses define a + function that maps points in the output image to points in the input image. + This warping engine runs a grid of points through this transform and uses + PIL's mesh transform to warp the image. + """ + filtering = Image.BILINEAR + resolution = 40 + + def get_transform(self, image): + """Return a transformation function, subclasses should override this""" + return lambda x, y: (x, y) + + def render(self, image): + r = self.resolution + xPoints = image.size[0] // r + 2 + yPoints = image.size[1] // r + 2 + f = self.get_transform(image) + + # Create a list of arrays with transformed points + xRows = [] + yRows = [] + for j in xrange(yPoints): + xRow = [] + yRow = [] + for i in xrange(xPoints): + x, y = f(i*r, j*r) + + # Clamp the edges so we don't get black undefined areas + x = max(0, min(image.size[0]-1, x)) + y = max(0, min(image.size[1]-1, y)) + + xRow.append(x) + yRow.append(y) + xRows.append(xRow) + yRows.append(yRow) + + # Create the mesh list, with a transformation for + # each square between points on the grid + mesh = [] + for j in xrange(yPoints-1): + for i in xrange(xPoints-1): + mesh.append(( + # Destination rectangle + (i*r, j*r, + (i+1)*r, (j+1)*r), + # Source quadrilateral + (xRows[j ][i ], yRows[j ][i ], + xRows[j+1][i ], yRows[j+1][i ], + xRows[j+1][i+1], yRows[j+1][i+1], + xRows[j ][i+1], yRows[j ][i+1]), + )) + + return image.transform(image.size, Image.MESH, mesh, self.filtering) + +class _PyCaptcha_SineWarp(_PyCaptcha_WarpBase): + """Warp the image using a random composition of sine waves""" + + def __init__(self, + amplitudeRange = (1,1),#(2, 6), + periodRange = (1,1)#(0.65, 0.73), + ): + self.amplitude = random.uniform(*amplitudeRange) + self.period = random.uniform(*periodRange) + self.offset = (random.uniform(0, math.pi * 2 / self.period), + random.uniform(0, math.pi * 2 / self.period)) + + def get_transform(self, image): + return (lambda x, y, + a = self.amplitude, + p = self.period, + o = self.offset: + (math.sin( (y+o[0])*p )*a + x, + math.sin( (x+o[1])*p )*a + y)) + +@view_config(route_name='captcha') +def DoCaptcha(request): + ImgSize = (230,100) + WorkImg = Image.new( 'RGBA', ImgSize, (255, 255, 255, 0) ) + Xmax, Ymax = WorkImg.size + # Write something on it + draw = ImageDraw.Draw(WorkImg) + + # use a truetype font + #font = ImageFont.truetype("/var/lib/defoma/gs.d/dirs/fonts/LiberationMono-Regular.ttf", 40) + # use it + font = ImageFont.truetype("jm2l/static/fonts/LiberationMono-Regular.ttf",40) + # Re-position + # Choose a word for captcha + text = random.choice(TabMots) + Xt, Yt = font.getsize(text) + OrX, OrY = (ImgSize[0]-Xt)//2, (ImgSize[1]-Yt)//2 + draw.text((OrX, OrY), text, font=font, fill="#000000") + # Apply a Blur + # WorkImg=WorkImg.filter(ImageFilter.BLUR) + # Apply a DETAIL + WorkImg=WorkImg.filter(ImageFilter.DETAIL) + # randomize parameters for perspective + ax, ay = (random.uniform(0.9,1.2) , random.uniform(0.9,1.2)) + tx, ty = (random.uniform(0,0.0003),random.uniform(0,0.0003)) + bx, by = (random.uniform(0.5,0.8),random.uniform(0,0.2)) + # Apply perspective to Captcha + WorkImg= WorkImg.transform(ImgSize, Image.PERSPECTIVE, (ax, bx, -25, by, ay, -10, tx, ty)) + # Apply SinWarp to Captcha + tr = Captcha_Img(Xmax, Ymax) + tr._image = WorkImg + WorkImg = tr.render() + # Apply a Smooth on it + WorkImg=WorkImg.filter(random.choice([ImageFilter.SMOOTH, ImageFilter.SMOOTH_MORE])) + # Save Result + request.session['Captcha'] = text + #session.save() + ImgHandle = BytesIO() + WorkImg.save(ImgHandle,'png') + ImgHandle.seek(0) + return Response(app_iter=ImgHandle, content_type = 'image/png') -- cgit v1.2.3-54-g00ecf