Pull to refresh

Captcha3d python

Прочитав статью Каптча 3d решил переписать код под PIL/python. Хотел спросить в комментариях, но увы авторизоваться не так то просто, поэтому оформляю статью и прилагаю код. Всё работает, возможно где-то не оптимизировано, т.к. делал аналог РНР-шнго кода. Увы есть проблема, с которой не сложилось. Текст в PIL (Python Imaging Library) вставляется со сглаженными краями, а необходим просто черный по белому без эффектов. Есть идея через промежуточное изображение b/w, но может есть более оригинальный выход. Если да, подскажите, буду рад.

#!/usr/bin/python
## -*- coding: utf-8 -*-

import ImageDraw, PIL, StringIO, string
from PIL import Image, ImageFont
from random import *
from math import *

class Captcha3d:

CHARS = 'WEafRTYIPAGHJKXBNM3479j';

hypot = 5
cimage = None

text = ''

def __init__(self):
#$this->time = microtime(true);
self.generateCode()
self.render()

def imageColorAllocate(self, r,g,b):
hexchars = "0123456789ABCDEF"
hexcolor = hexchars[r / 16] + hexchars[r % 16] + hexchars[g / 16] + hexchars[g % 16] + hexchars[b / 16] + hexchars[b % 16]
return int(hexcolor, 16)

def generateCode(self):
chars = self.CHARS;
self.text = "".join(choice(chars) for x in range(randint(3, 3)))

def getText(self):
return self.text

def getProection(self, x1,y1,z1):
x = x1 * self.hypot
y = z1 * self.hypot
z = -y1 * self.hypot

xx = 0.707106781187
xy = 0
xz = -0.707106781187

yx = 0.408248290464
yy = 0.816496580928
yz = 0.408248290464 # 1/sqrt(6)

cx = xx*x + xy*y + xz*z
cy = yx*x + yy*y + yz*z + 20*self.hypot

return [cx, cy]

def zFunction(self, x,y):
z = 2.6
if self.cimage.getpixel((y/2,x/2)) == (0,0,0):
z = 0
if z != 0:
z += float(randint(0,60))/100
z += 1.4 * sin((x+self.startX)*pi/15) * sin((y+self.startY)*pi/15)
return z

def render(self):
xx = 30
yy = 60
fontSans = ImageFont.truetype('FreeSans.ttf', 16)

self.cimage = Image.new("RGB", (yy * self.hypot, xx * self.hypot), (255,255,255))
draw = ImageDraw.Draw(self.cimage)

whiteColor = (255,255,255)
draw.rectangle([0, 0, yy * self.hypot, xx * self.hypot], fill=whiteColor)

textColor = (0,0,0)
#imgtext = Image.open("i8n.png")
#self.cimage.paste(imgtext, (0,0))
draw.text((2,0), self.text, font=fontSans, fill=textColor)

self.startX = randint(0,xx)
self.startY = randint(0,yy)

crd = {}

x = 0
while x < (xx+1):
y = 0
while y < (yy+1):
crd[str(x) + '&' + str(y)] = self.getProection(x,y,self.zFunction(x,y))
y += 1
x += 1

x = 0
while x < xx:
y = 0
while y < yy:
coord = []
coord.append((int(crd[str(x) + '&' + str(y)][0]),int(crd[str(x) + '&' + str(y)][1])))
coord.append((int(crd[str(x+1) + '&' + str(y)][0]),int(crd[str(x+1) + '&' + str(y)][1])))
coord.append((int(crd[str(x+1) + '&' + str(y+1)][0]),int(crd[str(x+1) + '&' + str(y+1)][1])))
coord.append((int(crd[str(x) + '&' + str(y+1)][0]),int(crd[str(x) + '&' + str(y+1)][1])))

c = int(self.zFunction(x,y)*32)
linesColor = (c,c,c)
draw.polygon(coord, fill=whiteColor, outline=linesColor)
#draw.polygon(coord, fill=whiteColor)
y += 1
x += 1

#draw.text((2,0), self.text, font=fontSans, fill=textColor)
#imageString($this->image, 1, 3, 0, (microtime(true)-$this->time), $textColor);

del draw
self.cimage.save("image.png", "PNG")
#return self.cimage

def main():
a = Captcha3d()
print a.getText()

if __name__ == '__main__':
main()
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.