因为注册登陆系统要验证码,就自己用python做了一个,留着以后用吧
有正常的干扰元素,带字符旋转
flag:还差做字符扭曲和自定义输入
import random
from PIL import Image, ImageDraw, ImageFont
class pil():
def __init__(self, width, height, mode=None, color=None):
"""
初始化--> 画文本--> (画干扰效果)--> 显示
:param mode: mode-->默认RGBA
:param width: 验证码的宽
:param height: 验证码的高
:param color: (num, num, num)
"""
self.mode = mode
if mode: # 默认RGBA
self.mode = mode
else:
self.mode = 'RGBA'
self.width = width
self.height = height
self.color = None
if color: # 默认(255, 255, 255)
self._color = color
else:
self._color = (255, 255, 255)
# 定义使用Image类实例化一个图片
self.img = Image.new(mode=self.mode, size=(self.width, self.height), color=self._color)
def draw_out(self):
# 把生成的图片保存为"pic.png"格式
with open('pic.png', 'wb') as f:
self.img.save(f, format='png')
# 显示图片
self.img.show()
# 画文本
def draw_text(self, font_path, num, number=True, a_font=False, A_font=False):
"""
若要添加字样,则设为true,数字默认开启
:param font_path: 字样文件
:param num: 验证码字符个数
:param number: 是否开启数字
:param a_font: 是否开启小写字母
:param A_font: 是否开启大写字母
:return: None
"""
self.img = Image.new(mode=self.mode, size=(self.width, self.height), color=self._color)
draw = ImageDraw.Draw(self.img, mode=self.mode)
# 定义字体
font1 = font_path
font = ImageFont.truetype(font1, 60) # 字体大小
data = self.get_font(number=number, a_font=a_font, A_font=A_font)
for i in range(num):
# 数字,大写字母,小谢字母
text = random.choice(data)
color = self.get_color()
draw.text([i * 50 + 12, -10], text, color, font=font)
def draw_text_rotate(self, font_path, num, number=True, a_font=False, A_font=False):
"""
若要添加字样,则设为true,数字默认开启
:param font_path: 字样文件
:param num: 验证码字符个数
:param number: 是否开启数字
:param a_font: 是否开启小写字母
:param A_font: 是否开启大写字母
:return: None
"""
self.img = Image.new(mode=self.mode, size=(self.width, self.height), color=self._color)
font1 = font_path
font = ImageFont.truetype(font1, 60)
data = self.get_font(number=number, a_font=a_font, A_font=A_font)
for i in range(num):
# 数字,大写字母,小谢字母
text = random.choice(data)
color = self.get_color()
global IMG
img0 = Image.new(mode=self.mode, size=(self.width, self.height),
color=(255, 255, 255))
draw0 = ImageDraw.Draw(img0, mode='RGBA')
draw0.text((0, 0), text, color, font=font)
# 获得一个旋转字
img1 = img0.rotate(random.uniform(-35, 35), Image.BILINEAR,
translate=((i * 65) + 25, 0), center=(0, 0),
expand=0)
if i == 0: # 当前旋转字与上一个叠加
IMG = img1
else:
IMG = Image.composite(img1, IMG, img1)
blank = Image.new(mode='RGBA', size=IMG.size, color=(255,) * 3) # 白背景
self.img = Image.composite(IMG, blank, IMG) # 补全旋转字的空缺
# 画干扰点
def draw_point(self, num):
# 生成img该对象上的画笔
draw = ImageDraw.Draw(self.img, mode=self.mode)
for i in range(num):
x = random.randint(0, self.width)
y = random.randint(0, self.height)
color = self.get_color()
draw.point([x, y], fill=color)
# self.draw_out()
# 画干扰园
def draw_arc(self, num):
# 生成img该对象上的画笔
draw = ImageDraw.Draw(self.img, mode=self.mode)
for i in range(num):
x = random.randint(0, self.width)
y = random.randint(0, self.height)
color = self.get_color()
draw.arc([x, y, x + 15, y + 15], 0, 360, fill=color)
# self.draw_out()
# 画干扰线
def draw_line(self, num):
# 生成img该对象上的画笔
draw = ImageDraw.Draw(self.img, mode=self.mode)
for i in range(num):
x1 = random.randint(0, self.width)
y1 = random.randint(0, self.height)
x2 = random.randint(0, self.width)
y2 = random.randint(0, self.height)
color = self.get_color()
draw.line([x1, y1, x2, y2], fill=color)
# self.draw_out()
def get_font(self, number=False, a_font=False, A_font=False):
data = []
if number:
for i in range(0, 10):
data.append(str(i))
if A_font:
for i in range(65, 91):
data.append(chr(i))
if a_font:
for i in range(97, 123):
data.append(chr(i))
return data
def get_color(self):
self.color = (random.randint(0, self._color[0]),
random.randint(0, self._color[1]), random.randint(0, self._color[2]))
return self.color
pil = pil(width=190, height=60)
pil.draw_text_rotate(font_path='UbuntuMono-B.ttf', num=3, a_font=True, A_font=True)
# pil.draw_text(font_path='UbuntuMono-B.ttf', num=4, a_font=True, A_font=True)
pil.draw_point(400)
pil.draw_arc(13)
pil.draw_line(6)
pil.draw_out()