Files
SMANAGE/backup/_api_backup/TempLateAPI/Verifox/test.py
T

126 lines
5.5 KiB
Python

from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
import string
def generate_text_captcha(width=200, height=80, char_count=4, font_size=40):
"""生成普通文字验证码(带干扰线和噪点)"""
# 1. 创建空白图片(背景色随机浅灰)
bg_color = (random.randint(200, 255), random.randint(200, 255), random.randint(200, 255))
image = Image.new('RGB', (width, height), bg_color)
draw = ImageDraw.Draw(image)
# 2. 生成随机字符(字母+数字)
chars = random.sample(string.ascii_letters + string.digits, char_count)
captcha_text = ''.join(chars)
# 3. 加载字体(需替换为本地字体路径,若无则注释此行用默认字体)
try:
font = ImageFont.truetype('simhei.ttf', font_size) # 黑体,需系统存在该字体
except:
font = ImageFont.load_default() # 默认字体
# 4. 绘制文字(随机颜色、位置、旋转角度)
for i, char in enumerate(captcha_text):
# 文字颜色(深色,与背景区分)
text_color = (random.randint(0, 100), random.randint(0, 100), random.randint(0, 100))
# 文字位置(避免超出边界)
x = 10 + i * (width // char_count)
y = random.randint(10, height - font_size - 10)
# 随机旋转(-15到15度)
angle = random.randint(-15, 15)
# 创建单个字符的临时图片并旋转
char_image = Image.new('RGBA', (font_size, font_size), (255, 255, 255, 0))
char_draw = ImageDraw.Draw(char_image)
char_draw.text((0, 0), char, font=font, fill=text_color)
char_image_rotated = char_image.rotate(angle, expand=True)
# 粘贴到主图
image.paste(char_image_rotated, (x, y), char_image_rotated)
# 5. 绘制干扰线(5-8条)
for _ in range(random.randint(5, 8)):
line_color = (random.randint(100, 200), random.randint(100, 200), random.randint(100, 200))
# 随机起点和终点
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=line_color, width=2)
# 6. 绘制噪点(100-200个)
for _ in range(random.randint(100, 200)):
noise_color = (random.randint(50, 150), random.randint(50, 150), random.randint(50, 150))
x = random.randint(0, width)
y = random.randint(0, height)
draw.point((x, y), fill=noise_color)
# 7. 轻微模糊处理
image = image.filter(ImageFilter.GaussianBlur(radius=0.5))
return image, captcha_text
# 生成并保存普通验证码
captcha_img, captcha_code = generate_text_captcha()
captcha_img.save('text_captcha.png')
print(f"普通验证码文字:{captcha_code}")
def generate_click_captcha(width=400, height=300, total_chars=12, target_count=4, font_size=30):
"""生成点击式文字验证码(返回目标文字坐标)"""
# 1. 创建背景图(随机渐变色)
image = Image.new('RGB', (width, height), (240, 240, 240))
draw = ImageDraw.Draw(image)
# 2. 生成随机字符集(中文+字母,增加复杂度)
# 中文样本(可扩展)
chinese_chars = '一二三四五六七八九十甲乙丙丁戊己庚辛壬癸金木水火土'
all_chars = list(chinese_chars + string.ascii_letters)
random.shuffle(all_chars)
# 总字符数和目标字符(需点击的4个)
used_chars = all_chars[:total_chars]
target_chars = random.sample(used_chars, target_count)
# 3. 加载字体(支持中文)
try:
font = ImageFont.truetype('simhei.ttf', font_size) # 需系统有中文字体
except:
font = ImageFont.load_default()
# 4. 随机分布字符并记录坐标
char_positions = {} # 存储 {字符: (中心x, 中心y)}
for char in used_chars:
# 随机位置(避免边缘)
x = random.randint(font_size, width - font_size)
y = random.randint(font_size, height - font_size)
# 随机颜色(区分度高)
color = (random.randint(0, 150), random.randint(0, 150), random.randint(0, 150))
# 随机旋转角度
angle = random.randint(-30, 30)
# 绘制带旋转的字符
char_img = Image.new('RGBA', (font_size*2, font_size*2), (255, 255, 255, 0))
char_draw = ImageDraw.Draw(char_img)
char_draw.text((font_size//2, font_size//2), char, font=font, fill=color)
char_rotated = char_img.rotate(angle, expand=True)
# 计算旋转后粘贴的位置(使中心对齐(x,y))
rx, ry = char_rotated.size
paste_x = x - rx//2
paste_y = y - ry//2
image.paste(char_rotated, (paste_x, paste_y), char_rotated)
# 记录中心坐标
char_positions[char] = (x, y)
# 5. 添加干扰元素(网格线)
for x in range(0, width, 40):
draw.line([(x, 0), (x, height)], fill=(200, 200, 200), width=1)
for y in range(0, height, 40):
draw.line([(0, y), (width, y)], fill=(200, 200, 200), width=1)
# 6. 获取目标字符的坐标
target_positions = {char: char_positions[char] for char in target_chars}
return image, target_chars, target_positions
# 生成并保存点击式验证码
click_img, target_chars, target_coords = generate_click_captcha()
click_img.save('click_captcha.png')
print(f"需点击的文字:{target_chars}")
print(f"对应坐标:{target_coords}")