代码:
# -*- coding: UTF-8 -*-from __future__ import unicode_literalsimport cStringIOimport loggingimport randomfrom PIL import Image, ImageDraw, ImageFontfrom django.utils import cryptologger = logging.getLogger('django')class VerificationCode(object): """ 验证码类 """ __r_g_b_list = [(200, 0, 0), (0, 200, 0), (0, 0, 200), (0, 200, 200), (200, 0, 200), (200, 200, 0), (235, 75, 75), (211, 44, 230), (136, 71, 255), (75, 105, 255), (94, 152, 217), (228, 174, 57), (106, 90, 205), (123, 104, 238), (65, 105, 225), (100, 149, 237), (70, 130, 180), (95, 158, 160), (102, 139, 139), (104, 131, 139), (100, 149, 237), (92, 172, 238), (205, 133, 63), (205, 133, 0)] def __init__(self, font_dir): """ 验证码类 :param font_dir: """ self.image_mode = 'RGB' self.width = 90 self.height = 35 self.image_color = (220, 220, 220) self.font_size = 20 self.font_list = self.__get_font_list(font_dir) self.ink_list = VerificationCode.__get_ink_list() def get_v_code_image_png(self): """ 生成验证码图像数据和验证码字符串 :return: """ v_code_str = crypto.get_random_string(length=4) _image = Image.new(self.image_mode, [self.width, self.height], self.image_color) draw = ImageDraw.Draw(_image) left_margin = -16 for i, _char in enumerate(v_code_str): left_margin += 20 top_margin = random.randrange(2, 16) draw.font = self.__get_random_font() draw.ink = self.__get_random_ink() if random.randint(0, 1): _char = _char.upper() draw.text([left_margin, top_margin], _char) if random.randint(0, 1): x1, y1, x2, y2 = self.__get_random_line() draw.line((x1, y1, x2, y2), 'MediumPurple') if random.randint(0, 1): x1, y1, x2, y2 = self.__get_random_line() draw.line((x1, y1, x2, y2), 'Thistle') if random.randint(0, 1): x1, y1, x2, y2 = self.__get_random_line() draw.line((x1, y1, x2, y2), 'Peru') del draw v_code_buf = cStringIO.StringIO() _image.save(v_code_buf, 'png') return v_code_buf, v_code_str def __get_random_font(self): """ 随机字体 :return: """ if self.font_list: font = random.choice(self.font_list) else: font = ImageFont.load_default() return font def __get_random_ink(self): """ 随机ink :return: """ if self.ink_list: ink = random.choice(self.ink_list) else: ink = 100 + 100 * 256 + 100 * 256 * 256 return ink def __get_random_line(self): """ 随机干扰线端点坐标 :return: """ x1 = random.randrange(int(self.width*.1), int(self.width*.9)) y1 = random.randrange(int(self.height*.1), int(self.height*.9)) x2 = random.randrange(int(self.width*-.6), int(self.width*.6)) + x1 y2 = random.randrange(-5, 5) + y1 return x1, y1, x2, y2 def __get_font_list(self, font_dir): """ :param font_dir: :return: """ # font file list file_list = [font_dir + '/FreeMono.ttf', font_dir + '/FreeMonoBold.ttf', font_dir + '/FreeMonoBoldOblique.ttf', font_dir + '/FreeMonoOblique.ttf', font_dir + '/FreeSans.ttf', font_dir + '/FreeSansBold.ttf', font_dir + '/FreeSansBoldOblique.ttf', font_dir + '/FreeSansOblique.ttf', font_dir + '/FreeSerif.ttf', font_dir + '/FreeSerifBold.ttf', font_dir + '/FreeSerifBoldItalic.ttf', font_dir + '/FreeSerifItalic.ttf'] font_list = list() for _file in file_list: try: font = ImageFont.truetype(_file, self.font_size) font_list.append(font) except BaseException as e: logger.error('get_font_list:%s' % e) return font_list @staticmethod def __get_ink_list(): """ :return: """ ink_list = [] for r, g, b in VerificationCode.__r_g_b_list: ink = r + g * 256 + b * 256 * 256 ink_list.append(ink) return ink_list
使用:
v_code_obj = VerificationCode(settings.GNU_DIR)def verification_code(request): """ 生成验证码 :param request: :return: """ v_code_buffer, v_code_str = v_code_obj.get_v_code_image_png() request.session['v_code'] = v_code_str.lower() return HttpResponse(v_code_buffer.getvalue(), 'image/png')
HTML页面: