每日一句
When it rains , look for rainbows.When it’s dark,look for stars.
生成随机图片验证码,可参考如下代码1所示:
import random
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont, ImageFilter
# pip install pillow
class VerifyCode():
def __init__(self):
self._letter_cases = 'abcdefghjkmnpqrstuvwxy'
self._upper_cases = self._letter_cases.upper()
self._numbers = ''.join(map(str, range(3, 10)))
pass
# 需要把monaco.ttf放到此程序目录下,下载地址https://github.com/todylu/monaco.ttf
def createCodeImage(self, size=(120, 30), img_type='jpg',
mode='RGB', bg_color=(255, 255, 255), fg_color=(0, 0, 255),
font_size=18, font_type='./Monaco.ttf',
length=4, draw_lines=True, n_line=(1, 2),
draw_points=True, point_chance=2):
width, height = size
# 定义使用Image类实例化一个长120,宽30,基于RGB的(255.255.255)颜色的图片
img = Image.new(mode, size, bg_color)
# 创建画笔,用于在图片上生成内容
draw = ImageDraw.Draw(img)
def get_chars():
return random.sample(self._letter_cases, length)
def creat_line():
line_num = random.randint(*n_line) # sign that the param is a list
for i in range(line_num):
begin = (random.randint(
0, size[0]), random.randint(0, size[1]))
end = (random.randint(0, size[0]), random.randint(0, size[1]))
draw.line([begin, end], fill=(0, 0, 0))
# 在图片上生成点
def create_points():
chance = min(100, max(0, int(point_chance)))
for w in range(width):
for h in range(height):
tmp = random.randint(0, 100)
if tmp > 100 - chance:
draw.point((w, h), fill=(0, 0, 0))
# 在图片上生成字符
def create_strs():
c_chars = get_chars()
strs = ' %s ' % ' '.join(c_chars)
font = ImageFont.truetype(font_type, font_size)
font_width, font_height = font.getsize(strs)
draw.text(((width - font_width) / 3, (height - font_height) / 3),
strs, font=font, fill=fg_color)
return ''.join(c_chars)
if draw_lines:
creat_line()
if draw_points:
create_points()
strs = create_strs()
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
]
img = img.transform(size, Image.PERSPECTIVE, params)
img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
return img, strs
def cre_code():
vecode = VerifyCode()
code_img, capacha_code = vecode.createCodeImage()
msstream = BytesIO()
code_img.save(msstream, "gif")
code = msstream.getvalue()
return code, capacha_code
image, text = cre_code()
# image 为二进制流
print(image)
print("图片验证码:%s" % text)
# with open('./ image.gif ', 'wb') as pic:
# pic.write(image)
为了服务端验证,还需要在请求验证码时请求一个ID,供后续服务器验证ID和验证码的值。
参考代码2如下:
from CAPTCHA import cre_code
class ImageCodeView(APIView):
"""图片验证码"""
def get(self, request, vcode_id):
# 生成验证码图片
image, text = cre_code()
# 保存真实值
# redis_conn = get_redis_connection('verify_codes')
# redis_conn.setex("img_%s" % vcode_id, 5 * 60, text)
print("图片验证码:%s" % text)
# 返回图片
return HttpResponse(image, content_type='image/gif')
代码1执行的结果参考如下所示:
保存到本地可见如下图片: