本文目录导读:

我来为你提供几种实现图片验证码生成的方法,从简单到复杂:
使用 Pillow 库(推荐)
from PIL import Image, ImageDraw, ImageFont
import random
import string
def generate_captcha(width=200, height=80, length=4):
"""
生成图片验证码
"""
# 创建画布
image = Image.new('RGB', (width, height), color='white')
draw = ImageDraw.Draw(image)
# 生成验证码文本
captcha_text = ''.join(random.choices(string.digits + string.ascii_uppercase, k=length))
# 添加干扰点
for _ in range(random.randint(50, 100)):
x = random.randint(0, width)
y = random.randint(0, height)
draw.point((x, y), fill=random_color())
# 添加干扰线
for _ in range(random.randint(3, 5)):
x1, y1 = random.randint(0, width), random.randint(0, height)
x2, y2 = random.randint(0, width), random.randint(0, height)
draw.line((x1, y1, x2, y2), fill=random_color(), width=2)
# 写入文字
for i, char in enumerate(captcha_text):
# 随机字体大小和颜色
font_size = random.randint(30, 45)
font = ImageFont.truetype("arial.ttf", font_size)
# 计算位置,让字符分布在画布上
x = 20 + i * (width // length)
y = random.randint(5, height - font_size - 5)
# 随机旋转字符
char_image = Image.new('RGBA', (font_size, font_size))
char_draw = ImageDraw.Draw(char_image)
char_draw.text((0, 0), char, fill=random_color(), font=font)
# 旋转
rotated_char = char_image.rotate(random.randint(-30, 30), expand=1)
# 粘贴到主图上
image.paste(rotated_char, (x, y), rotated_char)
return image, captcha_text
def random_color():
"""生成随机颜色"""
return (random.randint(50, 200), random.randint(50, 200), random.randint(50, 200))
# 使用示例
if __name__ == "__main__":
captcha_image, captcha_text = generate_captcha()
captcha_image.save("captcha.png")
print(f"验证码文本: {captcha_text}")
使用 captcha 库(最简单)
from captcha.image import ImageCaptcha
import random
import string
def generate_captcha_simple(length=4):
"""
使用captcha库生成验证码
"""
# 创建验证码生成器
image = ImageCaptcha(width=200, height=80, fonts=['arial.ttf'])
# 生成验证码文本
captcha_text = ''.join(random.choices(string.digits + string.ascii_uppercase, k=length))
# 生成图片
data = image.generate(captcha_text)
# 保存图片
image.write(captcha_text, 'captcha_simple.png')
return captcha_text
# 使用示例
print(f"验证码文本: {generate_captcha_simple()}")
高级版本(带更多干扰)
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
import string
import numpy as np
class AdvancedCaptcha:
def __init__(self, width=240, height=80):
self.width = width
self.height = height
self.image = None
self.draw = None
def generate(self, length=4):
"""生成高级验证码"""
# 创建背景
self.image = Image.new('RGB', (self.width, self.height),
color=self._random_bg_color())
self.draw = ImageDraw.Draw(self.image)
# 生成验证码文本
captcha_text = ''.join(random.choices(string.ascii_uppercase + string.digits, k=length))
# 添加各种干扰
self._add_noise()
self._add_lines()
self._add_text(captcha_text)
self._add_distortion()
# 添加滤镜效果
self.image = self.image.filter(ImageFilter.SMOOTH_MORE)
return self.image, captcha_text
def _random_bg_color(self):
"""生成随机背景色"""
return (random.randint(200, 255),
random.randint(200, 255),
random.randint(200, 255))
def _random_color(self, min_val=50, max_val=200):
"""生成随机颜色"""
return (random.randint(min_val, max_val),
random.randint(min_val, max_val),
random.randint(min_val, max_val))
def _add_noise(self):
"""添加噪点"""
for _ in range(random.randint(300, 500)):
x = random.randint(0, self.width - 1)
y = random.randint(0, self.height - 1)
self.draw.point((x, y), fill=self._random_color())
def _add_lines(self):
"""添加干扰线"""
for _ in range(random.randint(3, 6)):
x1 = random.randint(0, self.width // 2)
y1 = random.randint(0, self.height)
x2 = random.randint(self.width // 2, self.width)
y2 = random.randint(0, self.height)
self.draw.line(
[(x1, y1), (x2, y2)],
fill=self._random_color(100, 180),
width=random.randint(1, 3)
)
def _add_text(self, text):
"""添加文字"""
try:
font = ImageFont.truetype("arial.ttf", random.randint(35, 50))
except:
font = ImageFont.load_default()
for i, char in enumerate(text):
# 计算位置
x = 15 + i * (self.width // len(text))
y = random.randint(5, 15)
# 创建字符图片
char_img = Image.new('RGBA', (60, 60), (0, 0, 0, 0))
char_draw = ImageDraw.Draw(char_img)
# 绘制字符
char_draw.text((5, 5), char, fill=self._random_color(), font=font)
# 随机旋转
angle = random.randint(-25, 25)
rotated_img = char_img.rotate(angle, expand=1, fillcolor=(0, 0, 0, 0))
# 粘贴到主图
self.image.paste(rotated_img, (x, y), rotated_img)
def _add_distortion(self):
"""添加扭曲效果"""
# 使用简单的水波纹效果
self.image = self.image.transform(
self.image.size,
Image.MESH,
[(0, 0, self.width, self.height, 0, random.randint(-5, 5))],
resample=Image.BILINEAR
)
# 使用示例
if __name__ == "__main__":
captcha_generator = AdvancedCaptcha()
img, text = captcha_generator.generate()
img.save("advanced_captcha.png")
print(f"验证码文本: {text}")
带扭曲效果的验证码
from PIL import Image, ImageDraw, ImageFont
import random
import math
def generate_distorted_captcha():
width, height = 200, 80
image = Image.new('RGB', (width, height), (255, 255, 255))
draw = ImageDraw.Draw(image)
# 生成验证码
chars = ''.join(random.choices('ABCDEFGHJKLMNPQRSTUVWXYZ23456789', k=4))
# 添加波浪扭曲
for x in range(width):
for y in range(height):
# 计算偏移
offset_x = int(10 * math.sin(2 * math.pi * y / height * 2))
offset_y = int(10 * math.cos(2 * math.pi * x / width * 3))
new_x = (x + offset_x) % width
new_y = (y + offset_y) % height
pixel = image.getpixel((x, y))
# 这里简化处理,实际应用中需要更复杂的图像变换
# 写入字符
for i, char in enumerate(chars):
font = ImageFont.truetype("arial.ttf", 36)
x = 20 + i * 45
y = random.randint(10, 30)
draw.text((x, y), char, fill=random_color(), font=font)
return image, chars
def random_color():
return (random.randint(0, 150), random.randint(0, 150), random.randint(0, 150))
安装依赖
# 基础版本需要的库 pip install Pillow # 如果使用方法二 pip install captcha # 如果使用方法三(可选) pip install numpy
在Web应用中使用(Flask示例)
from flask import Flask, session, make_response
from io import BytesIO
app = Flask(__name__)
app.secret_key = 'your-secret-key'
@app.route('/captcha')
def get_captcha():
# 生成验证码
captcha_image, captcha_text = generate_captcha()
# 保存到session
session['captcha'] = captcha_text
# 转换为响应
buf = BytesIO()
captcha_image.save(buf, 'PNG')
buf.seek(0)
response = make_response(buf.getvalue())
response.headers['Content-Type'] = 'image/png'
return response
@app.route('/verify', methods=['POST'])
def verify_captcha():
user_input = request.form['captcha']
if user_input.upper() == session.get('captcha', '').upper():
return '验证成功!'
return '验证失败!'
注意事项
- 字体文件:确保系统有
arial.ttf字体,或者指定其他可用字体 - 验证码安全:避免使用容易被机器识别的简单字体和颜色
- 性能优化:生产环境建议使用缓存机制
- 存储:验证码文本通常存储在 session 或 redis 中
选择哪种方法取决于你的具体需求:
- 简单快速 → 方法一(Pillow)
- 最易实现 → 方法二(captcha库)
- 需要更多定制 → 方法三(高级版本)