Python 图片验证码生成代码与参数配置指南

远山来客
远山来客
发布时间:2026-10-12 | 2人浏览过
原创

本文详解如何利用 Python 与 Pillow 图像处理模块构建轻量级图片验证码生成器。通过封装统一接口,开发者可一键控制字符集、干扰线条、噪点分布及画面扭曲程度,快速获取字节流或直接保存为测试图像,适用于 Web 登录校验、API 安全拦截及自动化测试环境。

验证码生成目标与依赖准备

本方案旨在提供一个开箱即用的验证码绘制函数,核心目标是输出同时包含随机字母数字组合与视觉干扰元素的静态图像。在实际接入前,需确保运行环境满足以下基础条件:

  1. 安装 Python 解释器(推荐 3.6 及以上版本)
  2. 通过包管理器安装绘图依赖:pip install Pillow
  3. 准备可用的 TTF 字体文件(如 DejaVuSans.ttf 或系统默认无衬线字体)

准备就绪后,可将完整源码导入项目根目录进行独立调用。

核心代码实现与结构说明

以下为经过格式标准化与 Python 3 兼容性优化的完整实现。代码采用纯函数式结构,所有绘图参数均开放为可调字段:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import io

_letter_cases = "abcdefghjkmnpqrstuvwxy"
_upper_cases = "ABCDEFGHJKLMNPQRSTUVWXY"
_numbers = "1234567890"
init_chars = ''.join((_letter_cases, _upper_cases, _numbers))
default_font = "./DejaVuSans.ttf"


def generate_verify_image(size=(120, 30),
             chars=init_chars,
             img_type="PNG",
             mode="RGB",
             bg_color=(255, 255, 255),
             fg_color=(0, 0, 255),
             font_size=18,
             font_type=default_font,
             length=4,
             draw_lines=True,
             n_line=(1, 2),
             draw_points=True,
             point_chance=2,
             save_img=False):

  width, height = size
  img = Image.new(mode, size, bg_color)
  draw = ImageDraw.Draw(img)

  def get_chars():
    return random.sample(chars, length)

  def create_lines():
    line_num = random.randint(*n_line)
    for i in range(line_num):
      begin = (random.randint(0, size[0]), random.randint(0, size[1]))
      end = (random.randint(0, size[0]), random.randint(0, size[1]))
      draw.line([begin, end], fill=(0, 0, 0))

  def create_points():
    chance = min(100, max(0, int(point_chance)))
    for w in range(width):
      for h in range(height):
        tmp = random.randint(0, 100)
        if tmp > 100 - chance:
          draw.point((w, h), fill=(0, 0, 0))

  def create_strs():
    c_chars = get_chars()
    strs = ' %s ' % ' '.join(c_chars)
    font = ImageFont.truetype(font_type, font_size)
    font_width, font_height = font.getsize(strs)
    
    draw.text(((width - font_width) / 2, (height - font_height) / 2),
              strs, font=font, fill=fg_color)
    return ''.join(c_chars)

  if draw_lines:
    create_lines()
  if draw_points:
    create_points()
  
  actual_strs = create_strs()

  params = [
    1 - float(random.randint(1, 2)) / 100,
    0, 0, 0,
    1 - float(random.randint(1, 10)) / 100,
    float(random.randint(1, 2)) / 500,
    0.001,
    float(random.randint(1, 2)) / 500
  ]
  img = img.transform(size, Image.PERSPECTIVE, params)
  img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)

  mstream = io.BytesIO()
  img.save(mstream, img_type)

  if save_img:
    img.save("validate.png", img_type)

  return mstream, actual_strs


if __name__ == "__main__":
  mstream, strs = generate_verify_image(save_img=True)
  print(f"生成的验证码文本为: {strs}")

第1步:调用接口获取验证码流

在业务逻辑中引入该模块后,直接执行函数即可返回双返回值对象。左侧为内存中的二进制流,右侧为待校验的原始字符串。以 FastAPI 或 Flask 为例,可直接将字节流转 Base64 嵌入前端 <img> 标签的 src 属性,或通过中间件注入 HTTP Response Header。

第2步:调整关键参数优化验证效果

函数内部提供了精细的控制维度,可根据实际场景按需覆盖默认值:

  • size:设定画布宽高,默认 (120, 30)。过宽易导致字符间距过大,过窄则挤压变形
  • chars:自定义合法字符池,移除视觉上易混淆的符号(如 O/0, I/l)可提升人工核验通过率
  • n_line:干扰线数量区间元组,开启 draw_lines=True 后生效,建议范围 (1, 3)
  • point_chance:噪点触发概率阈值 [0, 100],数值越高画面越密,但需注意超出 50 会显著增加抗锯齿识别难度
  • img_type:输出格式,除默认 PNG 外支持 JPEG/GIF。若用于网页动态刷新,PNG 透明通道优势更明显

运行结果核对与常见问题排错

脚本执行无误后,终端应打印对应字符串并生成同名图像文件。若遇到运行中断或渲染异常,请按以下路径排查:

字体缺失或渲染方块

Pillow 默认读取 ./DejaVuSans.ttf。若未放置该文件,程序会抛出 OSError。请在操作系统字体目录(如 Windows 下的 C:\Windows\Fonts\Arial.ttf)寻找替代路径并赋值给 font_type 参数。

中文环境乱码排查

当前字符集仅包含英文字母与数字。若需扩展至汉字或 Emoji,需在初始化 chars 时补充 Unicode 编码段,并确保所选字体支持对应字形渲染。

依赖版本冲突

部分老旧系统预装 Pillow < 6.0 时,API 调用方式存在差异。如遇方法找不到报错,请升级至最新版本:pip install --upgrade Pillow。

简要总结

上述内容已完整覆盖 Python 图片验证码生成的核心逻辑、参数调节策略与典型故障排除路径。开发者可直接复制封装为工具类,快速集成至各类后台系统中。以上就是 Python 图片验证码生成的详细内容,更多关于 Python 图形图像处理与自动化校验的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表