方式一: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)