此为一个实验报告,故遵守实验报告的格式。
编写程序,绘制一个验证码图片,要求图片的背景为白色,同时该验证码有随机四位字母或者数字组成,在图片上还需要有干扰线,可以不需要干扰点。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: A.L.Kun
# @file: Verification.py
# @time: 2023/4/19 15:15
from random import choice, randint
from PIL import Image, ImageDraw, ImageFont
class Verification:
"""生成验证码图片的类"""
def __init__(self, n, draw_line, size, font_path, bgcolor, path):
self.draw_line = draw_line # 是否添加干扰线
self.n = n # 生成即为验证码
self.lis_all_code = [] # 存储获得的字母和数字
self.getAllCode() # 调用方法生成
self.bgcolor = bgcolor # 背景颜色
# print(self.lis_all_code) # 检测生成的字母和数字
self.ret = "" # 保存生成的验证码
self.size = size # 设置大小
self.font = font_path # 设置字体
self.save_path = path # 存储的路径
def getAllCode(self):
"""获得所有字母和数字,存储在列表中"""
for i in range(48, 58):
self.lis_all_code.append(chr(i))
for i in range(65, 91):
self.lis_all_code.append(chr(i))
self.lis_all_code.append(chr(i + 32))
def add_line(self, pen):
"""添加干扰线,要传入画笔"""
for i in range(randint(4, 8)): # 随机生成四到八条干扰线
# 颜色随机
randColor = (randint(0, 255), randint(0, 255), randint(0, 255))
# 起点随机
start = (randint(0, self.size[0]), randint(0, self.size[1]))
# 终点随机
end = (randint(0, self.size[0]), randint(0, self.size[1]))
# 画一条线
pen.line([start, end], fill=randColor)
def add_point(self, pen):
"""添加干扰点,传入画笔"""
for i in range(randint(20, 24)): # 生成随机个干扰点
# 颜色随机
randColor = (randint(0, 255), randint(0, 255), randint(0, 255))
# 起点随机
point = (randint(0, self.size[0]), randint(0, self.size[1]))
pen.point(point, fill=randColor)
def getImg(self):
"""获取验证码图片"""
img = Image.new("RGBA", self.size, self.bgcolor) # 创建一个图片
pen = ImageDraw.Draw(img) # 创建一个画笔
font = ImageFont.truetype(self.font, 25) # 实例化字体
for i in range(self.n): # 把文字写入图片中
string = choice(self.lis_all_code) # 生成随机的验证码
self.ret += string # 添加到结果中
font_color = (randint(0, 255), randint(0, 255), randint(0, 255)) # 颜色随机
# 验证码的初始横轴偏移量
x_start = randint(2, 5)
# 验证码的初始纵轴偏移量
y_start = 0
x = x_start + i * (self.size[0] // self.n) # 获取每个字横坐标的位置
y = randint(y_start, self.size[1] // 2) - 3 # 获取每个字纵坐标的位置
pen.text([x, y], string, font=font, fill=font_color) # 写入每一个字
if self.draw_line: # 如果要加干扰点线
self.add_line(pen)
self.add_point(pen)
return img
def main(self):
"""入口函数"""
img = self.getImg() # 获取图片
img.save(self.save_path) # 保存图片,因为里面有四色通道,所以要保存为png格式
ret = self.ret
self.ret = "" # 重置 self.ret 的值
return ret # 同时要返回随机的字符串
if __name__ == "__main__":
c = Verification(4, True, (100, 36), r'C:\Windows\Fonts\simfang.ttf', (255, 255, 255), "verify.png")
print(c.main())