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) # 每个坐标的画点概率10% self._draw_point(draw, 10) return captcha, text调用
if __name__ == '__main__': captcha = Captcha() imgObj, code = a.code() imgObj.save('test.png')结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)