- 生成验证码模块
| import random |
| from PIL import Image, ImageDraw, ImageFont, ImageFilter |
| |
| |
| def check_code(width=120, height=30, char_length=5, font_file='Monaco.ttf', font_size=28): |
| code = [] |
| """ |
| Image.new 方法用于创建一个新的图像对象。 |
| mode='RGB' 指定图像模式为RGB,即红、绿、蓝三原色。 |
| size=(width, height) 指定图像的尺寸。 |
| color=(255, 255, 255) 指定图像的背景颜色为白色(RGB值为255, 255, 255)。 |
| |
| ImageDraw.Draw对象用于在图像上绘制各种形状和文本。 |
| |
| ImageFont.truetype(font_file, font_size) 方法加载自定义字体文件。 |
| """ |
| img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255)) |
| |
| draw = ImageDraw.Draw(img, mode='RGB') |
| |
| |
| def random_char(): |
| """ |
| 生成随机字母 |
| :return: |
| """ |
| return chr(random.randint(65, 90)) |
| |
| |
| def random_color(): |
| """ |
| 生成随机颜色 |
| :return: |
| """ |
| return random.randint(0, 255), random.randint(10, 255), random.randint(64, 255) |
| |
| |
| font = ImageFont.truetype(font_file, font_size) |
| for i in range(char_length): |
| char = random_char() |
| code.append(char) |
| h = random.randint(0, 4) |
| draw.text([i * width / char_length, h], char, font=font, fill=random_color()) |
| """ |
| draw.text()在图像上绘制字符, |
| xy:文本的坐标(元组或列表),指定文本的左上角位置。 |
| text:要绘制的文本字符串。 |
| fill:文本的颜色(RGB元组)。 |
| font:字体对象(ImageFont.truetype 返回的对象),指定文本的字体和大小。 |
| |
| 字符的位置由 [i * width / char_length, h] 确定, |
| 其中 i * width / char_length 确保字符按宽度均匀分布,h 是字符的高度偏移量,char 是要绘制的字符, |
| font 是之前加载的字体, |
| fill 是字符的颜色,由 random_color 函数生成。 |
| """ |
| |
| |
| for i in range(40): |
| draw.point([random.randint(0, width), random.randint(0, height)], fill=random_color()) |
| """ |
| draw.point() 方法在 PIL(Pillow)库中用于在图像上绘制单个像素点 |
| xy:点的位置,通常是一个 (x, y) 坐标的元组或列表。 |
| fill:点的颜色,可以是 RGB 或 RGBA 的元组。 |
| |
| random.randint(0, width):生成一个从0到图像宽度 width 之间的随机整数,作为点的横坐标。 |
| random.randint(0, height):生成一个从0到图像高度 height 之间的随机整数,作为点的纵坐标。 |
| 这两个函数组合起来生成一个随机位置 (x, y),在图像的范围内。 |
| """ |
| |
| |
| for i in range(40): |
| draw.point([random.randint(0, width), random.randint(0, height)], fill=random_color()) |
| x = random.randint(0, width) |
| y = random.randint(0, height) |
| draw.arc((x, y, x + 4, y + 4), 0, 90, fill=random_color()) |
| """ |
| draw.arc() 方法在图像上绘制一个圆弧 |
| (x, y, x + 4, y + 4):定义了圆弧的边界框,即左上角和右下角的坐标。 |
| 0 和 90:分别是圆弧的起始角度和结束角度(单位为度),在这里是从0度到90度,即绘制一个四分之一圆。 |
| """ |
| |
| |
| for i in range(5): |
| x1 = random.randint(0, width) |
| y1 = random.randint(0, height) |
| x2 = random.randint(0, width) |
| y2 = random.randint(0, height) |
| |
| draw.line((x1, y1, x2, y2), fill=random_color()) |
| """ |
| draw.line() 方法在图像上绘制一条直线 |
| (x1, y1, x2, y2):定义了直线的起始点 (x1, y1) 和结束点 (x2, y2) 的坐标。 |
| """ |
| |
| |
| img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) |
| """ |
| img.filter():这是 PIL 库中的一个方法,用于对图像应用滤波器。 |
| ImageFilter.EDGE_ENHANCE_MORE:这是一个预定义的增强边缘滤波器,它可以增强图像中的边缘。 |
| |
| 验证码图像在生成后会被应用增强边缘滤波器,以增强图像中字符的边缘特征,从而使得验证码更加清晰和易于识别。 |
| """ |
| |
| |
| return img, ''.join(code) |
| |
| |
| if __name__ == '__main__': |
| |
| img, code = check_code() |
| |
| |
| |
| |
| |
| |
| |
| |
| from io import BytesIO |
| |
| stream = BytesIO() |
| img.save(stream, 'png') |
| stream.getvalue() |
| |
- 前端
| <div class="form-group"> |
| <label>{{ form.captcha.label }}</label> |
| <div class="row"> |
| <div class="col-xs-7"> |
| {{ form.captcha }} |
| <span style="color: red">{{ form.captcha.errors.0 }}</span> |
| </div> |
| <div class="col-xs-5"> |
| <img src="/captcha/"> |
| </div> |
| </div> |
| </div> |
- captcha模块
| def captcha(request): |
| img, code = check_code() |
| |
| |
| request.session['captcha'] = code |
| |
| request.session.set_expiry(60) |
| |
| stream = BytesIO() |
| img.save(stream, 'png') |
| |
| return HttpResponse(stream.getvalue()) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)