本文目录导读:

我来为你提供几种实现图片验证码生成的方法,从简单到复杂:
使用 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库)
- 需要更多定制 → 方法三(高级版本)
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播