下列代碼都是以自己的項目實例講述的,相關的文本內容很少,主要說明全在代碼註釋中 自製圖形驗證碼 這裡所說的圖形驗證碼都是自製的圖形,通過畫布、畫筆、畫筆字體的顏色繪製而成的。將驗證碼封裝成一個類比較好管理,代碼里有絕對詳細的註釋,當然大家可以直接複製。 裡面涉及的字體都是從系統電腦上自帶的,大家直接 ...
下列代碼都是以自己的項目實例講述的,相關的文本內容很少,主要說明全在代碼註釋中
自製圖形驗證碼
這裡所說的圖形驗證碼都是自製的圖形,通過畫布、畫筆、畫筆字體的顏色繪製而成的。將驗證碼封裝成一個類比較好管理,代碼里有絕對詳細的註釋,當然大家可以直接複製。
裡面涉及的字體都是從系統電腦上自帶的,大家直接複製當前目錄下就可以了。
主目錄/utils/captcha/__init__.py import random import string # Image:一個畫布 # ImageDraw:一個畫筆 # ImageFont:畫筆的字體 from PIL import Image, ImageDraw, ImageFont # Captcha驗證碼 class Captcha(object): # 生成4位數的驗證碼 numbers = 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): # 大小限在【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=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 = [ "PAPYRUS.TTF", "CENTAUR.TTF", "Inkfree.ttf", "verdana.ttf", ] font = random.choice(fonts) return "utils/captcha/"+font # 用來隨機生成一個字元串(包括英文和數字) @classmethod def gene_text(cls, numbers): # numbers是生成驗證碼的位數 return " ".join(random.sample(cls.SOURCE, numbers)) # 生成驗證碼 @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.numbers) # 獲取字體的尺寸 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) with open("captcha.png", "wb") as fp: image.save(fp) return text, image
顯示圖形驗證碼
一般圖形驗證碼都是在表單中,這樣短時間內的數據及建議保存在redis緩存中(用戶點擊動態刷新圖形驗證碼)。首先我們繪製圖形驗證碼保存到項目的目錄下(入口文件是主目錄(項目目錄)app.py文件,圖片也保存到主目錄下),然後通過url地址訪問自製的圖形驗證碼(這裡我只添加主要的代碼)
主目錄/common/views.py @bp.route("/captcha") def graph_captcha(): """ 使用定義好的圖形驗證碼類,來製作驗證碼 以驗證碼為鍵、驗證碼為值(為了用戶的體驗,讓其忽略大小寫)存儲在redis緩存中 通過BytesIO位元組流的方式保存和訪問圖片 :return: 圖片響應 """ # 獲取驗證碼 text, image = Captcha.gene_graph_captcha() cpcache.set(text.lower(), text.lower()) # BytesIO:位元組流 out = BytesIO() # 保存圖片 image.save(out, "png") # 存儲完圖片,將文件的指針指向文件頭,使下次保存圖片能覆蓋前面保存的圖片,節省空間 out.seek(0) # 訪問圖片,並將其作為一個響應返回給前臺 resp = make_response(out.read()) resp.content_type = "image/png" return resp
前端頁面的代碼如下:
<div class="form-group"> <div class="input-group"> <input type="text" class="form-control" name="graph_captcha" placeholder="圖形驗證碼"> <span class="input-group-addon captcha-addon"> <img id="captcha-img" class="captcha-img" src="{{ url_for("common.graph_captcha") }}" alt=""> </span> </div> </div>
動態刷新驗證碼
無非就是再生成一張圖形驗證碼,通過url再次訪問就可以,但是這樣做是非常麻煩的,這裡我很難解釋(很難!!!),大家就直接複製代碼吧,這個代碼就是點擊圖片生成一個新的url訪問圖片
這個文件放在公共的目錄下就可以了 var cpparam = { 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 paramArray = queryArray[i].split("="); if(paramArray[0] == key){ paramArray[1] = value; queryArray[i] = paramArray.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; } };
對應html的js文件就需要實現元素(圖片)點擊刷新圖片,調用上面的變數cpparam生成一章圖片並訪問。
$(function(){ $("#captcha-img").on("click", function(){ var self = $(this); var src = self.attr("src"); var newsrc = cpparam.setParam(src, "xx", Math.random()); self.attr("src", newsrc); }); });