圖片驗證碼生成
安裝pillow
pip install pillow
在utils下新建python package命名為captcha
把需要需要用到的字體放在captcha下

編輯captcha.__init__.py, 生成驗證碼
import random import string # Image:一個畫布 # ImageDraw:一個畫筆 # ImageFont:畫筆的字體 # pip install pillow from PIL import Image, ImageDraw, ImageFont class Captcha(object): # 生成幾位數的驗證碼 number = 4 # 驗證碼圖片的高度和寬度 size = (100, 30) # 驗證碼字體大小 fontsize = 25 #加入干擾線條數 line_number = 2 #構建一個驗證碼源文本 SOURCE = list(string.ascii_letters) for index in range(0, 10): SOURCE.append(str(index)) #用來繪制干擾線 @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.__gene_random_color(), width=2) # 用來繪制干擾點 @classmethod def __gene_points(cls, draw, point_chance, width, height): chance = min(100, max(0, int(point_chance))) #大小限制在[0, 100] for w in range(width): for h in range(height): tmp = random.randint(0, 100) if tmp > 100 - chance: draw.point((w, h), fill=cls.__gene_random_color()) # 生成隨機的顏色 @classmethod def __gene_random_color(cls, start=0, end=255): random.seed() return (random.randint(start, end),random.randint(start, end), random.randint(start, end)) # 隨機選擇一個字體 @classmethod def __gene_random_font(cls): fonts = [ 'Courgette-Regular.ttf', 'LHANDW.TTF', 'Lobster-Regular.ttf', 'verdana.ttf' ] font = random.choice(fonts) return 'utils/captcha/' + font # 用來隨機生成一個字符串 @classmethod def gene_text(cls, number): #num是生成驗證碼的位數 return ''.join(random.sample(cls.SOURCE, number)) # 生成驗證碼 @classmethod def gene_graph_captcha(cls): #驗證碼圖片的高和寬 width, height = cls.size #創建圖片 image = Image.new('RGBA', (width,height),cls.__gene_random_color(0, 100)) #驗證碼的字體 font = ImageFont.truetype(cls.__gene_random_font(), cls.fontsize) #創建畫筆 draw = ImageDraw.Draw(image) #生成字符串 text = cls.gene_text(cls.number) #獲取字體尺寸 font_width, font_height = font.getsize(text) #填充字符串 draw.text(((width - font_width) / 2, (height - font_height) / 2), text, font=font, fill=cls.__gene_random_color(150, 255)) #繪制干擾線 for x in range(0, cls.line_number): cls.__gene_line(draw, width, height) #繪制噪點 cls.__gene_points(draw, 10, width, height) return (text, image)
測試的時候我發現有些字體會導致程序崩潰,所以,我只設置了一個字體 fonts = ['verdana.ttf']
編輯視圖。我們把它放到 公共的common里面去,編輯common.views.py
from flask import Blueprint, make_response from utils.captcha import Captcha from io import BytesIO bp = Blueprint('common', __name__, url_prefix='/c') #common太長,改為c @bp.route('/') def index(): return 'common index' @bp.route('/graph_captcha/') def graph_captcha(): text, image = Captcha.gene_graph_captcha() out = BytesIO() image.save(out, 'png') out.seek(0) resp = make_response(out.read()) resp.content_type = 'image/png' return resp
訪問http://127.0.0.1:5000/c/graph_captcha/

圖片驗證放到注冊頁面。點擊一次更換一張
圖片驗證碼放在注冊頁面比較簡單,只需要把編輯front_signup.html,把里面的“圖片驗證碼”字換成img標簽,src設置成圖片驗證碼的url
<div class="input-group"> <input type="text" class="form-control" name="graph_captcha" placeholder="圖形驗證碼"> <span class="input-group-addon captcha-addon"> <!--加了一個類captcha-addon--> <img id="captcha-img" src="{{ url_for('common.graph_captcha') }}"><!--加了id aptcha-img--> </span> </div> <!--樣式--> .captcha-addon{ padding: 0; //這是內邊距為0,因為input-group-addon有設置內邊距 overflow: hidden; //當里面的元素超出則隱藏 } #captcha-img{ height: 32px; //設置圖片的高度為32px cursor: pointer; //當鼠標移到圖片上變成手的圖標 }

還有個需求就是,我們點擊一個圖片驗證碼,則需要更換成另外一個。
圖片驗證碼更換,只需要替換它的url就可以,但是它的url就是一個http://127.0.0.1:5000/common/captcha/
所以只需要請求的時候加個參數http://127.0.0.1:5000/front/captcha/?xxx=<隨機數>即可
我還需要對?xxx=<隨機數>做處理,不然當用戶點擊多次,?xxx=<隨機數>&xxx=<隨機數>...變得很長,而我們只需要一個就可以了,這里封裝了一個js, 存放在static/common/js/bbsparams.js中
/** * Created by Administrator on 2017/3/24. */ var bbsparam = { setParam: function (href,key,value) { // 重新加載整個頁面 var isReplaced = false; var urlArray = href.split('?'); if(urlArray.length > 1){ var queryArray = urlArray[1].split('&'); for(var i=0; i < queryArray.length; i++){ var paramsArray = queryArray[i].split('='); if(paramsArray[0] == key){ paramsArray[1] = value; queryArray[i] = paramsArray.join('='); isReplaced = true; break; } } if(!isReplaced){ var params = {}; params[key] = value; if(urlArray.length > 1){ href = href + '&' + $.param(params); }else{ href = href + '?' + $.param(params); } }else{ var params = queryArray.join('&'); urlArray[1] = params; href = urlArray.join('?'); } }else{ var param = {}; param[key] = value; if(urlArray.length > 1){ href = href + '&' + $.param(param); }else{ href = href + '?' + $.param(param); } } return href; } };
然后在static/front/js/下新建front_signup.js,當點擊圖片時更換src
$(function(){ $('#captcha-img').click(function (event) { var self = $(this); var src = self.attr('src'); var newsrc = bbsparam.setParam(src,'xx',Math.random()); self.attr('src',newsrc); }); });
在signup.html中引入上面兩個js
<script src="{{ url_for('static', filename='common/js/bbsparam.js') }}"></script>
<script src="{{ url_for('static', filename='front/js/front_signup.js') }}"></script>
