Python使用PIL生成验证码

from PIL import Image,ImageDraw,ImageFont,ImageTk
import os
import tkinter as tk
import tkinter.messagebox
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"]=["SimHei"]

class Code:                                                       #产生验证码
    def __init__(self):
        self.k = 0

    def randomChr(self):                                      #随机产生验证码数字和大小写字母
        a = chr(np.random.randint(65,90))
        b = chr(np.random.randint(97,122))
        c = chr(np.random.randint(48,57))
        return np.random.choice([a,b,c])

    #随机产生画布背景
    def randomColor1(self):
        return tuple(np.random.randint(150,255,3))

    def alpha(self,img1):                                     #扣黑色背景并旋转
        img1 = img1.convert("RGBA")
        img1 = np.array(img1)
        for i in range(img1.shape[0]):
            for j in range(img1.shape[1]):
                c = (img1[i, j, 0]) | (img1[i, j, 1]) | (img1[i, j, 2])      #或运算
                if c == 0:
                   img1[i, j, :] = 0
        img2 = Image.fromarray(img1)
        img2 = img2.rotate(np.random.uniform(-45,45))
        # print(img2)
        return img2

    def code(self):
        img = Image.fromarray(np.uint8(np.random.randint(50, 150, (60, 240, 3))))              #产生噪声背景
        draw = ImageDraw.Draw(img)
        global data
        data = []
        for j in range(4):                                                     #产生旋转的字符并加到噪声背景上
            data1 = self.randomChr()
            data.append(data1)
            font = ImageFont.truetype("Inkfree.ttf", size=np.random.randint(30, 52))
            img1 = Image.fromarray(np.uint8(np.zeros((60, 60, 3))))          # 创建黑色背景
            draw1 = ImageDraw.Draw(img1)
            draw1.text((10,0),data1,font=font,fill=self.randomColor1(),stroke_width=1,spacing=10)    #stroke_width是字体粗细
            img1 = self.alpha(img1)
            x = 60*max(0,(j-0.6*np.random.rand()))+10*np.random.rand()+10
            y = -8+np.random.randint(15)
            img.paste(img1,(int(x),int(y)), mask=img1)                        #将透明的字符和噪声背景叠加

        for i in np.arange(np.random.randint(1,4)):                           #产生随机线条
            draw.line(xy=(np.random.uniform(5,220),np.random.uniform(10,60),np.random.uniform(5,220),
                          np.random.uniform(5,60)),fill=self.randomColor1(),width=np.random.randint(2,5))   #点1(x,y),2(x,y)

        # plt.imshow(img)
        # plt.show()
        # img1.show()

        # if not os.path.exists("auth_code"):                  #判断是否有这个文件夹
        #     os.mkdir("auth_code")                           # 当前目录下创建文件夹
        #     img.save(os.path.join("auth_code", "{}.jpg".format(self.k)))     #将图片加入文件夹
        # else:
        #     img.save(os.path.join("auth_code", "{}.jpg".format(self.k)))
        # self.k += 1
        # img.save("code.jpg")   #保存到当前文件夹
        return img


#
# if __name__ == '__main__':
#     code = Code()
#     code.code()




def sure():                                              #点击确定的执行操作
    if str("".join(data)).lower() == (var_put.get()).lower():
        tk.messagebox.showinfo(message="输入正确")
    else:
        if "" == var_put.get():
            tk.messagebox.showinfo(message="输入为空")
            next_photo()
        else:
            tk.messagebox.showinfo(message="输入错误")
            next_photo()

def next_photo():                                             #更换验证码
    global image1                                       #必须声明全局变量
    img = code.code()                                  # 获取验证码图像信息
    image1 = ImageTk.PhotoImage(img)
    img_label.configure(imag=image1)                  #替换img_label窗口验证码

window = tk.Tk()                          #定义窗口
window.title("my window")                 #窗口名称和大小
window.geometry("400x200")

code = Code()                                      #获取类
img = code.code()                                 #获取验证码图像信息
image = ImageTk.PhotoImage(img)                  #转换成tk的形式
img_label = tk.Label(window, imag=image)        #用label绑定到window
img_label.pack()                               #显示验证码

l = tk.Label(window, text="请输入验证码", font=("Arial", 12)).place(x=50,y=70)     # 定义内容(哪个窗口上,内容,背景色,字体,背景的长宽)
l1 = tk.Label(window, text="(不区分大小写)", font=("Arial", 10)).place(x=50,y=90)

var_put = tk.StringVar()                         #初始化输入框的值
e = tk.Entry(window, show=None,textvariable = var_put).place(x=170,y=80)        # *输入文本的框,显示*号  None显示文字     textvariable捕捉输入值
b1 = tk.Button(window, text="确定", width=10, height=1, command=sure).place(x=130,y=130)  # 可点击模块(输出窗口,显示文字内容,大小,功能)
b2 = tk.Button(window, text="换一张", width=10, height=1, command=next_photo).place(x=240, y=130)  # 可点击模块(输出窗口,显示文字内容,大小,功能)

window.mainloop()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值