天天看點

利用PIL生成圖檔驗證碼

利用pillow生成圖檔驗證碼

安裝pillow

pip install pillow
           

導入子產品

from PIL import Image, ImageDraw, ImageFont
           

生成圖檔驗證碼

  • 建立圖檔
img = Image.new(mode="RGB", size=(, ), color="white")
#這裡需要三個參數,第一個是指定mode,這裡使用RGB模式,第二個指定的圖檔尺寸,第三個指定圖檔顔色
           
  • 建立一個畫筆對象
draw = ImageDraw.Draw(img, "RGB")  # 執行個體畫筆對象
#這裡的兩個參數,第一個是指定一塊畫布(個人了解,在什麼地方開始你的創作),第二個同上mode
           
  • 指定字型樣式和大小
font = ImageFont.truetype("static/font/kumo.ttf", )  
# 指定字型樣式和大小,這裡用的是kumo.ttf這個樣式(需要下載下傳),參數一檔案的路徑,參數二字型大小
           

詳細代碼

def get_validCode(request):
    width = #指定圖檔的長高
    height = 

    def rndColor():
        """
        生成随機顔色
        :return:
        """
        return (random.randint(, ), random.randint(, ), random.randint(, ))

    img = Image.new(mode="RGB", size=(width, height), color="white")
    draw = ImageDraw.Draw(img, "RGB")  # 執行個體畫筆對象
    font = ImageFont.truetype("static/font/kumo.ttf", )  # 指定字型樣式和大小
    valid_list = []  # 用于存儲随機驗證碼
    for i in range():  # 生成5位數的随機字元
        random_num = str(random.randint(, ))  # 随機數字
        random_lower = chr(random.randint(, ))  # 随機小寫字母
        random_upper = chr(random.randint(, ))  # 随機小寫字母

        random_char = random.choice([random_num, random_lower, random_upper])  # 随機選擇

        draw.text([ + i * , ], random_char, rndColor(), font=font)
        # 這裡清單裡的兩個參數表示橫縱坐标,在img裡面的,第二個參數表示文本内容,第三個是顔色,第四個是字型大小
        valid_list.append(random_char)  # 将随機生成的驗證碼字元串添加到清單中
    for i in range():  # 加噪點
        draw.point([random.randint(, width), random.randint(, height)], fill=rndColor())
    for i in range():  # 加幹擾線,這裡通過添加多組橫縱坐标實作
        x1 = random.randint(, width)
        y1 = random.randint(, height)
        x2 = random.randint(, width)
        y2 = random.randint(, height)
        x3 = random.randint(, width)
        y3 = random.randint(, height)

        draw.line((x1, y1, x2, y2, x3, y3), fill=rndColor())
    f = BytesIO()  # 相當于擷取檔案句柄
    img.save(f, "png")  # 存入記憶體,以png的格式
    data = f.getvalue()  # 從記憶體中取出來

    valid_str = "".join(valid_list)  # 轉化成随機的字元串格式

    request.session["keepValidCode"] = valid_str  # 将随機字元串放入session中
    return HttpResponse(data)#這裡需要交給前端的ajax處理
           

前端代碼

{#<!DOCTYPE html>#}//這裡寫了一個簡單的登入頁面
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/sweet/sweetalert2.min.css">
    <script src="/static/js/jquery-3.2.1.min.js"></script>
    <script src="/static/js/bootstrap.min.js"></script>
    <script src="/static/js/jquery.cookie.js"></script>
    <script src="/static/sweet/sweetalert2.min.js"></script>

</head>
<body style="background-color: #f8f8f8">
<div class="container   col-md-4 col-lg-offset-4 ">

    <div class="panel panel-info " style="margin-top: 100px">
        <div class="panel-heading" style="padding: 5px 0">
            <h4 class="text-center">請登入</h4>
        </div>
        <div class="row">
            <div class="panel-body col-md-10 col-md-offset-1">
                <form method="post">
                    {% csrf_token %}
                    <div class="form-group user">
                        <label for="exampleInputEmail1">使用者名:</label>
                        <input type="text" class="form-control" id="exampleInputEmail1">
                        <span id="helpBlock2" class="help-block"></span>
                    </div>
                    <div class="form-group">
                        <label for="exampleInputPassword1">密碼:</label>
                        <input type="password" class="form-control" id="exampleInputPassword1">
                        <span id="helpBlock3" class="help-block"></span>
                    </div>
                    <div class="row">
                        <div class="form-group  col-md-6">
                            <label for="validateCode">驗證碼:</label>
                            <input type="password" class="form-control" id="validateCode">
                            <span id="helpBlock4" class="help-block"></span>
                        </div>
                        <div class="col-md-6">
                            <img src="/get_validCode/" alt="" width="150px" height="40px" style="margin-top: 20px;" id="imgCode">
                        </div>
                    </div>

                    <div class="form-group">
                        <span class="failed" style="color: red"></span>
                    </div>
                    <div class="form-group col-lg-offset-4 col-md-4">
                        <input type="button" value="登&nbsp;&nbsp;錄" class="form-control btn-primary" id="login">

                    </div>

                </form>
                <div class="from-group">
                    <span class="form-group pull-right"><span>還沒有賬号?<a href="/register/">點選注冊</a></span></span>
                </div>
            </div>

        </div>
    </div>

</div>
<script>
{#    $("#imgCode").on("click",function () {#}
{#        $(this)[].src += "?"#}
{#    });#}
$("#imgCode").on("click",function () {
    $.ajax({
        url: "/get_validCode/",
        type: "GET",
        success: function (data) {
            $("#imgCode").attr("src", "/get_validCode/")
        }

    })
});





$("#login").on("click", function () {

        $.ajax(
                {
                    url: "/sign_in/",
                    type: "POST",
                    headers: {"X-CSRFToken": $.cookie('csrftoken')},
                    data: {
                        user: $("#exampleInputEmail1").val(),
                        pwd: $("#exampleInputPassword1").val(),
                        validCode:$("#validateCode").val()

                    },
                    success: function (data) {

                        var dat = JSON.parse(data);

                        if (dat["state"] == "success") {
                            swal(
                                    '',
                                    '登入成功,正在跳轉...',
                                    'success'
                            );
                            setTimeout(function () {
                                window.location.href = "/index/";
                            }, );

                        }
                        if (dat["state"] == "user_none") {
                            $("#exampleInputEmail1").focus();
                            var use = $("#helpBlock2");
                            use.parent().addClass("has-error");
                            use.html("請輸入使用者名")
                        }
                        if (dat["state"] == "pwd_none") {
                            $("#exampleInputPassword1").focus();
                            var pwd = $("#helpBlock3");
                            pwd.parent().addClass("has-error");
                            pwd.html("請輸入登入密碼")
                        }
                        if (dat["state"] == "validCode_none"){
                            $("#validateCode").focus();
                            var valid = $("#helpBlock4");
                            valid.parent().addClass("has-error");
                            valid.html("請輸入驗證碼")
                        }
                        if (dat["state"] == "validCode_error"){
                            $("#validateCode").focus();
                            var valid_error = $("#helpBlock4");
                           valid_error.parent().addClass("has-error");
                            valid_error.html("驗證碼錯誤")
                        }
                        if (dat["state"] == "failed") {

                            swal(
                                    '',
                                    '使用者名或密碼錯誤',
                                    'error'
                            )
                        }


                    }
                }
        )
    });
</script>
</body>
</html>
           

視圖函數

def sign_in(request):#貌似寫的太啰嗦了,登入的函數
    if request.method == "GET":
        return render(request, "login.html")

    elif request.method == "POST":
        state = {"state": None}
        username = request.POST.get("user")
        if username == "":
            state["state"] = "user_none"
            return HttpResponse(json.dumps(state))
        password = request.POST.get("pwd")
        if password == "":
            state["state"] = "pwd_none"
            return HttpResponse(json.dumps(state))

        validCode = request.POST.get("validCode")
        if validCode == "":
            state["state"] = "validCode_none"
            return HttpResponse(json.dumps(state))
        if validCode.upper() == request.session.get("keepValidCode").upper():
            user = auth.authenticate(username=username, password=password)
            if user:
                state["state"] = "success"
                auth.login(request, user)
            else:
                state["state"] = "failed"
            return HttpResponse(json.dumps(state))
        else:
            state["state"] = "validCode_error"
        return HttpResponse(json.dumps(state))