ai_v/services/captcha_service.py

52 lines
1.8 KiB
Python

import random
import string
import io
from PIL import Image, ImageDraw, ImageFont, ImageFilter
class CaptchaService:
@staticmethod
def generate_captcha():
# 生成随机 4 位字符
chars = string.ascii_uppercase + string.digits
captcha_text = ''.join(random.choices(chars, k=4))
# 图像参数
width, height = 120, 50
background = (255, 255, 255)
image = Image.new('RGB', (width, height), background)
draw = ImageDraw.Draw(image)
# 尝试加载字体,如果失败则使用默认
try:
# 在 Windows 上寻找常用路径
font_path = "C:\\Windows\\Fonts\\arial.ttf"
font = ImageFont.truetype(font_path, 32)
except:
font = ImageFont.load_default()
# 绘制文本
for i, char in enumerate(captcha_text):
# 随机颜色和轻微旋转/偏移
color = (random.randint(0, 150), random.randint(0, 150), random.randint(0, 150))
draw.text((15 + i * 25, 5), char, font=font, fill=color)
# 增加噪点线
for _ 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.randint(0, 255), random.randint(0, 255), random.randint(0, 255)), width=1)
# 增加噪点点
for _ in range(30):
draw.point((random.randint(0, width), random.randint(0, height)), fill=(0, 0, 0))
# 轻微模糊
image = image.filter(ImageFilter.SMOOTH)
# 保存到内存
buf = io.BytesIO()
image.save(buf, format='PNG')
return captcha_text, buf.getvalue()