Python生成圖片驗證碼

方式一:redis

# -*- coding: utf-8 -*-
import random,os
import string
# pip install Pillow
# Image:是一個畫板(context),ImageDraw:是一個畫筆, ImageFont:畫筆的字體
from PIL import Image,ImageDraw,ImageFont
from common_utils.lqredis import SiteRedis


# Captcha驗證碼
class Captcha(object):
    # 把一些常量抽取成類屬性
    #字體的位置
    font_path = os.path.dirname(os.path.realpath(__file__)) + '/verdana.ttf'
    #生成幾位數的驗證碼
    number = 4
    #生成驗證碼圖片的寬度和高度
    size = (100,30)
    #背景顏色,默認爲白色 RGB(Re,Green,Blue)
    bgcolor = (255,255,255)
    #隨機字體顏色
    fontcolor = (random.randint(0,100),random.randint(0,100),random.randint(0,100))
    # 驗證碼字體大小
    fontsize = 25
    #隨機干擾線顏色。
    linecolor = (random.randint(0,220),random.randint(0,255),random.randint(0,100))
    # 是否要加入干擾線
    draw_line = True
    # 是否繪製干擾點
    draw_point = True
    # 加入干擾線的條數
    line_number = 3

    SOURCE = list(string.letters)
    for index in range(0, 10):
        SOURCE.append(str(index))

    #用來隨機生成一個字符串(包括英文和數字)
    # 定義成類方法,而後是私有的,對象在外面不能直接調用
    @classmethod
    def gene_text(cls):
        # return ''.join(random.sample(cls.SOURCE,cls.number))#number是生成驗證碼的位數
        return ''.join(random.sample('01234567898',4))

    #用來繪製干擾線
    @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.linecolor)

    # 用來繪製干擾點
    @classmethod
    def __gene_points(cls,draw,point_chance,width,height):
        chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100]
        for w in xrange(width):
            for h in xrange(height):
                tmp = random.randint(0, 100)
                if tmp > 100 - chance:
                    draw.point((w, h), fill=(0, 0, 0))

    #生成驗證碼
    @classmethod
    def gene_code(cls):
        width,height = cls.size #寬和高
        image = Image.new('RGBA',(width,height),cls.bgcolor) #建立圖片
        font = ImageFont.truetype(cls.font_path,cls.fontsize) #驗證碼的字體
        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.fontcolor) #填充字符串
        # 若是須要繪製干擾線
        if cls.draw_line:
            # 遍歷line_number次,就是畫line_number根線條
            for x in xrange(0,cls.line_number):
                cls.__gene_line(draw,width,height)
        # 若是須要繪製噪點
        if cls.draw_point:
            cls.__gene_points(draw,10,width,height)

        return (text,image)


    #用來驗證驗證的函數
    @classmethod
    def check_captcha(cls,captcha):
        captcha_lower = captcha.lower()
        if SiteRedis.get_keys(captcha_lower):
            SiteRedis.dele(captcha_lower)
            return True
        else:
            return False


#圖形驗證碼
def graph_captcha():
    # 得到文體和圖片
    text, image = Captcha.gene_code()
    # StringIO 至關因而一個管道
    out = StringIO()
    # 把StringIO 塞進這個管道中,並指定圖片的格式
    image.save(out, 'png')
    # 將StringIO的指針指向開始的位置
    out.seek(0)
    # 生成一個響應對象,out,read是把圖片流讀出來
    response = make_response(out.read())
    # 指定響應的類型n
    response.content_type = 'image/pag'
    SiteRedis.set(text.lower(), text.lower(), expire='60')
    return response

方式二:app

from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
import cv2,sys
import numpy as np
import matplotlib.pyplot as plt

path = sys.path[0] + '/verdana.ttf'  # 選擇字體



# random chr
def rndChar():
    return chr(random.randint(65, 90))  # 隨機字母


def rndInt():
    return str(random.randint(0, 9))  # 隨機數字


def rndColor():
    return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))  # 隨機顏色


def rndColor2():
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))  # 隨機顏色


def gaussian_noise():  # 高斯噪聲
    mu = 125
    sigma = 20
    return tuple((np.random.normal(mu, sigma, 3).astype(int)))


def rotate(x, angle):  # 旋轉
    M_rotate = cv2.getRotationMatrix2D((x.shape[0] / 2, x.shape[1] / 2), angle, 1)
    x = cv2.warpAffine(x, M_rotate, (x.shape[0], x.shape[1]))
    return x


width = 180 * 4
height = 180


def gen_image(num):
    for l in range(num):

        image = Image.new('RGB', (width, height), (255, 255, 255))  # 先生成一張大圖

        font = ImageFont.truetype(path, 36)

        draw = ImageDraw.Draw(image)  # 新的畫板

        for x in range(0, width):
            for y in range(0, height):
                draw.point((x, y), fill=rndColor())

        label = []

        for t in range(4):  # 每一張驗證碼4個數字
            numb = rndInt()
            draw.text((180 * t + 60 + 10, 60 + 10), numb, font=font, fill=rndColor2())
            label.append(numb)

        with open(sys.path[0] + "/label.txt", "a") as f:
            for s in label:
                f.write(s + ' ')
            f.writelines("\n")  # 寫入label

        img = image.filter(ImageFilter.GaussianBlur(radius=0.5))
        img = np.array(img)

        img1 = np.array([])

        for i in range(0, 4):
            img0 = img[:, 180 * i: 180 * i + 180]  # 提取含有驗證碼的小圖
            angle = random.randint(-45, 45)
            img0 = rotate(img0, angle)  # 對小圖隨機旋轉

            if img1.any():
                img1 = np.concatenate((img1, img0[60:120, 60:120, :]), axis=1)

            else:
                img1 = img0[60:120, 60:120, :]

        plt.imsave(sys.path[0] + '/' + str(l) + '.jpg', img1)  # 保存結果


if __name__ == '__main__':
    gen_image(5)

方式三:dom

from captcha.image import ImageCaptcha
# 驗證碼的包
from PIL import Image
import random
import time
# 系統模塊
import os


def random_captcha():
    captcha_text = []
    for i in range(4):
        c = random.choice(['0', '1', '2', '3', '4'])
        captcha_text.append(c)
    return ' '.join(captcha_text)  # 字符串中間沒有空格

# 生成驗證碼方法
def gen_capthca():
    image = ImageCaptcha()
    captcha_text = random_captcha()
    captcha_image = Image.open(image.generate(captcha_text))
    return captcha_text, captcha_image



# 定義圖片個數
count = 5
# 定義圖片文件夾
path = './captcha_image'
if not os.path.exists(path):
    os.makedirs(path)

# 循環建立圖片
for i in range(count):
# 定義建立時間
    now = str(int(time.time()))
    # 接收字符串和圖片
    text, image = gen_capthca()
    # 定義圖片名稱
    filename = text + '_' + now + '.png'
    # 存儲圖片
    image.save(path + os.path.sep + filename)
    print('saved %s' % filename)
相關文章
相關標籤/搜索