随笔- 310  文章- 1  评论- 0  阅读- 86066 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
from io import BytesIO
import random, math
from PIL import Image, ImageDraw, ImageFont, ImageFilter
from flask import Flask,session, make_response
 
 
class vieCode:
    __fontSize = 20  # 字体大小
    __width = 120  # 画布宽度
    __heigth = 45  # 画布高度
    __length = 5  # 验证码长度
    __draw = None  # 画布
    __img = None  # 图片资源
    __code = None  # 验证码字符
    __str = None  # 自定义验证码字符集
    __inCurve = True  # 是否画干扰线
    __inNoise = True  # 是否画干扰点
    __type = 2  # 验证码类型 1、纯字母  2、数字字母混合
    __fontPatn = '1.ttf'  # 字体
 
    def GetCodeImage(self, size=80, length=5):
        '''获取验证码图片
           @param int size 验证码大小
           @param int length 验证码长度
        '''
        # 准备基础数据
        self.__length = length
        self.__fontSize = size
        self.__width = self.__fontSize * self.__length
        self.__heigth = int(self.__fontSize * 1.5)
 
        # 生成验证码图片
        self.__createCode()
        self.__createImage()
        self.__createNoise()
        self.__printString()
        self.__cerateFilter()
 
        return self.__img, self.__code
 
    def __cerateFilter(self):
        '''模糊处理'''
        self.__img = self.__img.filter(ImageFilter.BLUR)
        filter = ImageFilter.ModeFilter(8)
        self.__img = self.__img.filter(filter)
 
    def __createCode(self):
        '''创建验证码字符'''
        # 是否自定义字符集合
        if not self.__str:
            # 源文本
            number = "3456789"
            srcLetter = "qwertyuipasdfghjkzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
            srcUpper = srcLetter.upper()
            if self.__type == 1:
                self.__str = number
            else:
                self.__str = srcLetter + srcUpper + number
 
        # 构造验证码
        self.__code = random.sample(self.__str, self.__length)
 
    def __createImage(self):
        '''创建画布'''
        bgColor = (random.randint(200, 255), random.randint(200, 255), random.randint(200, 255))
        self.__img = Image.new('RGB', (self.__width, self.__heigth), bgColor)
        self.__draw = ImageDraw.Draw(self.__img)
 
    def __createNoise(self):
        '''画干扰点'''
        if not self.__inNoise:
            return
        font = ImageFont.truetype(self.__fontPatn, int(self.__fontSize / 1.5))
        for i in range(5):
            # 杂点颜色
            noiseColor = (random.randint(150, 200), random.randint(150, 200), random.randint(150, 200))
            putStr = random.sample(self.__str, 2)
            for j in range(2):
                # 绘杂点
                size = (random.randint(-10, self.__width), random.randint(-10, self.__heigth))
                self.__draw.text(size, putStr[j], font=font, fill=noiseColor)
        pass
 
    def __createCurve(self):
        '''画干扰线'''
        if not self.__inCurve:
            return
        x = y = 0
 
        # 计算曲线系数
        a = random.uniform(1, self.__heigth / 2)
        b = random.uniform(-self.__width / 4, self.__heigth / 4)
        f = random.uniform(-self.__heigth / 4, self.__heigth / 4)
        t = random.uniform(self.__heigth, self.__width * 2)
        xend = random.randint(self.__width / 2, self.__width * 2)
        w = (2 * math.pi) / t
 
        # 画曲线
        color = (random.randint(30, 150), random.randint(30, 150), random.randint(30, 150))
        for x in range(xend):
            if w != 0:
                for k in range(int(self.__heigth / 10)):
                    y = a * math.sin(w * x + f) + b + self.__heigth / 2
                    i = int(self.__fontSize / 5)
                    while i > 0:
                        px = x + i
                        py = y + i + k
                        self.__draw.point((px, py), color)
                        i -= i
 
    def __printString(self):
        '''打印验证码字符串'''
        font = ImageFont.truetype(self.__fontPatn, self.__fontSize)
        x = 0
        # 打印字符到画板
        for i in range(self.__length):
            # 设置字体随机颜色
            color = (random.randint(30, 150), random.randint(30, 150), random.randint(30, 150))
            # 计算座标
            x = random.uniform(self.__fontSize * i * 0.95, self.__fontSize * i * 1.1)
            y = self.__fontSize * random.uniform(0.3, 0.5)
            # 打印字符
            self.__draw.text((x, y), self.__code[i], font=font, fill=color)
 
# 生成验证码
def get_captcha():
    image, code = vieCode().GetCodeImage()
    code = ''.join(code).lower()
    out = BytesIO()
    session["code"] = code
    image.save(out, 'png')
    out.seek(0)
    resp = make_response(out.read())
    resp.content_type = 'image/png'
    return resp, code
 
app = Flask(__name__)
app.secret_key = 's3cr3t'
@app.route('/')
def index():
    response,code = get_captcha()
    print("code",code)
    return response
 
if __name__ == '__main__':
    app.run(debug=True)

 

 

 posted on   boye169  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
点击右上角即可分享
微信分享提示