验证码类
import string
import random
from PIL import Image, ImageDraw, ImageFont
class Captcha:
def __init__(self, captcha_size=(150, 50),
font_size=40, font_style=None, text_number=6,
line_number=6, background_color=(255, 255, 255),
sources=None):
"""
:param captcha_size: 验证码Size:tuple
:param font_size: 字体Size:int
:param font_style: 字体样式:ttf文件路径
:param text_number: 验证码数量:int
:param line_number: 干扰线条数量:int
:param background_color: 验证码背景:rgb
:param sources: 验证码源:str
"""
self.captcha_width = captcha_size[0]
self.captcha_height = captcha_size[-1]
self.font_size = font_size
self.text_number = text_number
self.line_number = line_number
self.background_color = background_color
if font_style:
self.font_style = font_style
else:
self.font_style = 'simkai.ttf'
if sources:
self.sources = sources
else:
self.sources = string.ascii_letters + string.digits
def _get_text(self):
text = random.sample(self.sources, k=self.text_number)
return ''.join(text)
def _font_color(self):
return random.randint(0, 150), random.randint(0, 150), random.randint(0, 150)
def _other_color(self):
return random.randint(0, 250), random.randint(0, 250), random.randint(0, 250)
def _draw_line(self, draw):
begin = (random.randint(0, self.captcha_width // 2), random.randint(0, self.captcha_height // 2))
end = (random.randint(self.captcha_width // 2, self.captcha_width),
random.randint(self.captcha_height // 2, self.captcha_height))
draw.line([begin, end], fill=self._other_color())
def _draw_point(self, draw, point_chance):
for w in range(self.captcha_width):
for h in range(self.captcha_height):
tmp = random.randint(0, 100)
if tmp < point_chance:
draw.point((w, h), fill=self._other_color())
def _draw_text(self, draw, text, font, spacing=20):
"""
:param draw: 画布对象:ImageDraw
:param text: 验证码:str
:param font: 字体对象:ImageFont
:param spacing: 验证码间隙:int
"""
text_width, text_height = font.getsize(text)
char_length = int(text_width / self.text_number)
total_spacing = (self.text_number - 1) * spacing
true_width = total_spacing + text_width
true_height = text_height
if true_width >= self.captcha_width:
raise ValueError('字体加中间空隙超过图片总宽度')
start_width = int((self.captcha_width - true_width) / 2)
start_height = int((self.captcha_height - true_height) / 2)
for value in text:
position = start_width, start_height
draw.text(position, value, font=font, fill=self._font_color())
start_width = start_width + char_length + spacing
def code(self):
captcha = Image.new('RGB', (self.captcha_width, self.captcha_height), self.background_color)
font = ImageFont.truetype(self.font_style, self.font_size)
draw = ImageDraw.Draw(captcha)
text = self._get_text()
self._draw_text(draw, text, font, spacing=5)
for _ in range(self.line_number):
self._draw_line(draw)
self._draw_point(draw, 10)
return captcha, text
调用
if __name__ == '__main__':
captcha = Captcha()
imgObj, code = a.code()
imgObj.save('test.png')
结果
|