1. 程式人生 > >圖片驗證碼功能實現

圖片驗證碼功能實現

自定義圖片驗證類

import os
import time
import random

from PIL import Image, ImageDraw, ImageFont


class Captcha(object):
    def __init__(self, request):
        """
        初始化,設定各種屬性
        """
        self.django_request = request
        self.session_key = "_django_captcha_key"
        self.captcha_expires_time 
= "_django_captcha_expires_time" # 驗證碼圖片尺寸 self.img_width = 90 self.img_height = 30 def _get_font_size(self, code): """ 將圖片高度的80%作為字型大小 """ s1 = int(self.img_height * 0.8) s2 = int(self.img_width / len(code)) return int(min((s1, s2)) + max((s1, s2)) * 0.05)
def _set_answer(self, answer): """ 設定答案和過期時間 """ self.django_request.session[self.session_key] = str(answer) self.django_request.session[self.captcha_expires_time] = time.time() + 60 def _make_code(self): """ 生成隨機數或隨機字串 """ string
= random.sample("abcdefghkmnpqrstuvwxyzABCDEFGHGKMNOPQRSTUVWXYZ23456789", 4) self._set_answer("".join(string)) return string def get(self): """ 生成驗證碼圖片,返回值為圖片的bytes """ background = (random.randrange(200, 255), random.randrange(200, 255), random.randrange(200, 255)) code_color = (random.randrange(0, 50), random.randrange(0, 50), random.randrange(0, 50), 255) font_path = os.path.join(os.path.normpath(os.path.dirname(__file__)), "timesbi.ttf") image = Image.new("RGB", (self.img_width, self.img_height), background) code = self._make_code() font_size = self._get_font_size(code) draw = ImageDraw.Draw(image) # x是第一個字母的x座標 x = random.randrange(int(font_size * 0.3), int(font_size * 0.5)) for i in code: # 字元y座標 y = random.randrange(1, 7) # 隨機字元大小 font = ImageFont.truetype(font_path.replace("\\", "/"), font_size + random.randrange(-3, 7)) draw.text((x, y), i, font=font, fill=code_color) # 隨機化字元之間的距離 字元粘連可以降低識別率 x += font_size * random.randrange(6, 8) / 10 self.django_request.session[self.session_key] = "".join(code) return image def check(self, code): """ 檢查使用者輸入的驗證碼是否正確 """ _code = self.django_request.session.get(self.session_key) or "" if not _code: return False expires_time = self.django_request.session.get(self.captcha_expires_time) or 0 # 注意 如果驗證之後不清除之前的驗證碼的話 可能會造成重複驗證的現象 del self.django_request.session[self.session_key] del self.django_request.session[self.captcha_expires_time] if _code.lower() == str(code).lower() and time.time() < expires_time: return True else: return False

使用

def img2base64(img):
    with BytesIO() as buf:
        img.save(buf, "gif")
        buf_str = buf.getvalue()
    img_prefix = "data:image/png;base64,"
    b64_str = img_prefix + b64encode(buf_str).decode("utf-8")
    return b64_str
HttpResponse(json.dumps(img2base64(Captcha(request).get())))