安裝
pip install pillow
代碼貼圖
import os
import string
import random
# Image:是一個畫板(context) ImageDraw:是一個畫筆 ImageFont:畫筆的字體
from PIL import Image, ImageDraw, ImageFont
class Captcha:
# 字體的路徑
font_path = os.path.join(os.path.dirname(__file__), 'NuevaStd-Italic.otf')
# 驗證碼位數(shù)
number = 4
# 驗證碼尺寸(寬高)
size = (120, 48)
# 背景顏色,默認為白色 rgb(red,green,blue)
bg_color = (12, 12, 12)
# 隨機字體顏色
font_color = (random.randint(230, 255), random.randint(200, 255), random.randint(100, 255))
# 驗證碼字體大小
font_size = 36
# 隨機干擾線顏色。
line_color = (random.randint(123, 250), random.randint(100, 200), random.randint(0, 100))
# 是否繪制干擾線
is_draw_line = True
# 是否繪制干擾點
is_draw_point = True
# 干擾線的數(shù)量
line_number = 5
# 生成 a~zA~Z1~9 字符串
SOURCE = list(string.ascii_letters)
for index in range(1, 10):
SOURCE.append(str(index))
@classmethod
def gene_text(cls):
"""
用來隨機生成一個字符串(包括英文和數(shù)字)
:return: text 返回文本
"""
# number是生成驗證碼的位數(shù)
text = ''.join(random.sample(cls.SOURCE, cls.number))
return text
@classmethod
def __gene_line(cls, draw, width, height):
"""繪制干擾線"""
begin = (random.randint(0, width), random.randint(0, height))
end = (random.randint(0, width), random.randint(0, height))
draw.line([begin, end], fill=cls.line_color)
@classmethod
def __gene_points(cls, draw, point_chance, width, height):
"""繪制干擾點"""
# 大小限制在[0, 100]
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))
@classmethod
def gene_code(cls):
"""
繪制圖形驗證碼
:return: [text, image]
"""
# 寬和高
width, height = cls.size
# 創(chuàng)建圖片
image = Image.new('RGBA', (width, height), cls.bg_color)
# 驗證碼的字體
font = ImageFont.truetype(cls.font_path, cls.font_size)
# 創(chuàng)建畫筆
draw = ImageDraw.Draw(image)
# 生成驗證碼字符串
text = cls.gene_text()
# 獲取字體寬高
font_width, font_height = font.getsize(text)
# 填充字符串
draw.text(((width - font_width) / 2, (height - font_height) / 2), text, font=font, fill=cls.font_color)
# 如果需要繪制干擾線
if cls.is_draw_line:
# 遍歷 line_number 次, 就是畫l ine_number 根線條
for x in range(0, cls.line_number):
cls.__gene_line(draw, width, height)
# 如果需要繪制噪點
if cls.is_draw_point:
cls.__gene_points(draw, 10, width, height)
return [text, image]
渲染在頁面上
Flask 實現(xiàn)
import flask
from io import BytesIO
from utils.captcha.captcha import Captcha
def graph_captcha():
# 生成驗證碼
text,image = Captcha.gene_code()
# BytesIO 相當(dāng)于一個管道
out = BytesIO()
# 把image塞到BytesIO這個管道中
image.save(out,'png')
# 指針指向開始的地方 0
out.seek(0)
# 創(chuàng)建一個response響應(yīng)對象, out.read是把圖形讀出來
response = flask.make_response(out.read())
# 指定響應(yīng)的類型
response.content_type = 'image/png'
return response
Django 實現(xiàn)
from django.http import HttpResponse
from io import BytesIO
from utils.captcha.captcha import Captcha
def graph_captcha(request):
# 生成驗證碼
captcha, image = Captcha.gene_code()
# BytesIO 相當(dāng)于一個管道
out = BytesIO()
# 創(chuàng)建一個response響應(yīng)對象, out.read是把圖形讀出來
image.save(out, 'png')
# 指針指向開始的地方 0
out.seek(0)
response = HttpResponse(content_type="image/png")
response.write(out.read())
return response