class ImageCode:
# 通过数字获取ascii表中的对应字母
@staticmethod
def get_char(length):
sources = "0123xcrfvbgtyhn456zjumi789qweasdklopQAZXSWEDCFVRTGYBHNJUMIKOLP"
data = ""
for i in range(length):
# random.randint(begin, end) 返回begin<= i <=end 左闭右闭区间
data += sources[random.randint(0, 61)]
return data
# return chr(random.randint(65, 90))
# 获取随机颜色
@staticmethod
def get_color(*args):
if args == ():
return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
while True:
text_color = ImageCode.get_color()
aberration = 3 * (text_color[0] - args[0][0]) ** 2 + 4 * (text_color[0] - args[0][1]) ** 2 + 2 * (
text_color[0] - args[0][2]) ** 2
# 设置字体颜色与背景色差,值越大,字体越清晰,机器人就更容易识别,相对应的代价就是需要随机更多次的RGB值。
# 极端情况验证码字体背景rgb均为128,aberration最小的最大值为147456
rgb2 = 100000
if aberration > rgb2:
return text_color
@staticmethod
def get_img(char_code_length):
"""
获取验证码图片
:param char_code_length: 验证码长度
:return:
"""
# 创建图片对象
img_back = ImageCode.get_color()
img_width = 120
img_height = 50
img = Image.new(mode='RGB', size=(img_width, img_height), color=img_back)
# 创建画笔对象
draw = ImageDraw.Draw(img, mode='RGB')
# 噪点 xy:基于图片的坐标,fill表示点颜色
for i in range(100):
draw.point([random.randint(0, img_width), random.randint(0, img_height)], fill=ImageCode.get_color())
# 噪线 xy:(起点坐标,终点坐标) fill:颜色 width:线宽
# draw.line((50, 30, 100, 60),fill='purple', width=5)
for i in range(20):
draw.line([random.randint(0, img_width), random.randint(0, img_height), random.randint(0, img_width),
random.randint(0, img_height)],
fill=ImageCode.get_color())
# 划圆或弧线
for i in range(30):
x = random.randint(0, img_width)
y = random.randint(0, img_height)
x2 = x + 4
y2 = y + 4
draw.arc((x, y, x2, y2), 0, 90, fill=ImageCode.get_color())
from MR_ERP import settings
path = os.path.join(settings.BASE_DIR, "static", "fonts", "setofont.ttf")
font = ImageFont.truetype(path, 30)
# 用来拼接验证码字符的
char_code = ImageCode.get_char(char_code_length)
for i in range(char_code_length):
char = char_code[i]
height = random.randint(10, 15)
draw.text([18 * (i + 1), height], char, ImageCode.get_color(img_back), font=font)
# 模糊效果和边缘增强效果
# img = img.filter(ImageFilter.BLUR)
# img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
# img.show()
# print(char_code)
return img, char_code
返回图片给前端:
class GeneralAuthCode(APIView):
"""
get: 获取验证码
"""
@staticmethod
def get(request):
try:
img, char_code = ImageCode.get_img(4)
key = str(idCreatorUtil.appKeyWorker.get_id())
# 保存验证码到redis
authCodeUtil.create_auth_code(key, char_code)
buf = io.BytesIO()
img.save(buf, "png")
result_dict = {
"img_code": 'data:image/png;base64,' + base64.b64encode(buf.getvalue()).decode(),
"key": key
}
buf.close()
return resultUtil.result(status=200, msg="success", data=result_dict)
# 前端直接显示图片
# data = buf.getvalue()
# buf.close()
# return HttpResponse(data, content_type="image/jpeg")
except Exception:
traceback.print_exc()
return resultUtil.error_500_result()