52 lines
1.8 KiB
Python
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()
|