import os
import random
import string
from io import BytesIO
from config import BASE_DIR
from PIL import Image, ImageDraw, ImageFont, ImageFilter
class _CreateCaptcha:
def __init__(self):
# 字体路径
self.font_path = os.path.join(BASE_DIR, 'app/static/fonts/arial.ttf')
# 生成验证码位数
self.text_num = 4
# 生成图片尺寸
self.pic_size = (100, 40)
# 背景颜色,默认为白色
self.bg_color = (255, 255, 255)
# 字体颜色,默认为蓝色
self.text_color = (0, 0, 255)
# 干扰线颜色,默认为红色
self.line_color = (255, 0, 0)
# 是否加入干扰线
self.draw_line = True
# 加入干扰线条数上下限
self.line_number = (1, 5)
# 是否加入干扰点
self.draw_points = True
# 干扰点出现的概率(%)
self.point_chance = 2
self.image = Image.new('RGBA', (self.pic_size[0], self.pic_size[1]), self.bg_color)
self.font = ImageFont.truetype(self.font_path, 25)
self.draw = ImageDraw.Draw(self.image)
self.text = self.gene_text()
def gene_text(self):
# 随机生成一个字符串
source = list(string.ascii_letters)
for i in range(0, 10):
source.append(str(i))
return ''.join(random.sample(source, self.text_num))
def gene_line(self):
# 随机生成干扰线
begin = (random.randint(0, self.pic_size[0]), random.randint(0, self.pic_size[1]))
end = (random.randint(0, self.pic_size[0]), random.randint(0, self.pic_size[1]))
self.draw.line([begin, end], fill=self.line_color)
def gene_points(self):
# 随机绘制干扰点
for w in range(self.pic_size[0]):
for h in range(self.pic_size[1]):
tmp = random.randint(0, 100)
if tmp > 100 - self.point_chance:
self.draw.point((w, h), fill=(0, 0, 0))
def gene_code(self):
# 生成验证码图片
font_width, font_height = self.font.getsize(self.text)
self.draw.text(
((self.pic_size[0] - font_width) / self.text_num, (self.pic_size[1] - font_height) / self.text_num),
self.text,
font=self.font,
fill=self.text_color
)
if self.draw_line:
n = random.randint(self.line_number[0], self.line_number[1])
# print(n)
for i in range(n):
self.gene_line()
if self.draw_points:
self.gene_points()
params = [
1 - float(random.randint(1, 2)) / 100,
0,
0,
0,
1 - float(random.randint(1, 10)) / 100,
float(random.randint(1, 2)) / 500,
0.001,
float(random.randint(1, 2)) / 500
]
self.image = self.image.transform((self.pic_size[0], self.pic_size[1]), Image.PERSPECTIVE, params) # 创建扭曲
self.image = self.image.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强
return self.image
def generate_picture():
"""
返回一个图片和对应的字符
"""
_obj = _CreateCaptcha()
return _obj.gene_code(), _obj.text
def generate_buf_picture():
"""
返回图片的二进制数据和对应的字符
"""
_obj = _CreateCaptcha()
_img = _obj.gene_code()
_buf = BytesIO()
_img.save(_buf, 'BMP')
_img.close()
_img_bin_data = _buf.getvalue()
return _img_bin_data, _obj.text
if __name__ == "__main__":
img, char = generate_picture()
print('验证码: ', char)
img.show()
generate img
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
相关阅读更多精彩内容
- 该文章属于转载,感谢原作者:cofface 目前新的高通机型boot.img或recovery.img解包后均带有...
- 先看看如下的 HTML: <!DOCTYPE html> 在浏览器开发者工具中可以看到,div 的高度要高于 im...
- 1,问题现象: img[src=""] img无路径情况下,安卓会出现一个方形边框 img[src=""] img...
- 贴一段代码先 多张图片通过canvas合成跨域问题 Uncaught DOMException: Failed t...