小白都能看得懂的教程 一文教你實作生成隨機影像驗證碼
大家好,我叫亓官劼(qí guān jié ),三本計算機在讀,目前在積極準備21計算機考研中,同時也在學習后端開發,準備作業,不敢孤注一擲,因為要留條后路;不求兩全其美在,因為那需要運氣+機遇;只求學有所得,慢慢成長,CSDN中記錄學習的點滴歷程,時光荏苒,未來可期,加油~
博主博客文章內容導航(實時更新)
更多優質文章推薦:
- 收藏!最詳細的Python全堆疊開發指南 看完這篇你還不會Python全堆疊開發 你來打我!!!
- 一本教你如何在前端實作富文本編輯器
- 小白都能看得懂的教程 一本教你如何在前端實作markdown編輯器
- 一文教會你Bootstrap,讓你也可以快速建站
- 一文教你如何白嫖JetBrains全家桶(IDEA/PtChram/CLion)免費正版
- 小白都能看懂的實戰教程 手把手教你Python Web全堆疊開發 (DAY 1)
- 小白都能看懂的實戰教程 手把手教你Python Web全堆疊開發 (DAY 2)
- 小白都能看懂的實戰教程 手把手教你Python Web全堆疊開發 (DAY 3)
- 小白都能看懂的實戰教程 手把手教你Python Web全堆疊開發 (DAY 4)
- 小白都能看懂的實戰教程 手把手教你Python Web全堆疊開發 (DAY 5)
- 小白都能看懂的實戰教程 手把手教你Python Web全堆疊開發 (DAY 6)
- 小白都能看懂的實戰教程 手把手教你Python Web全堆疊開發 (DAY 7)
??**寫在前面,文末附有完整原始碼,如果不想看的寫的話,可以直接拿去使用!**本期小白都能看得懂的教程將會帶領你實作我們的生成隨機驗證碼的功能,這里演示的專案是我們之前教程中的(收藏!最詳細的Python全堆疊開發指南 看完這篇你還不會Python全堆疊開發 你來打我!!!)沒看過這個教程也無所謂,我們幾乎不會使用專案中的東西,僅作為演示使用,
準備作業
??好了,下面進入正題,我們來實作這個功能,首先這個是使用Python3進行開發的,我們需要用到一個PIL的庫,這里安裝庫的pip3命令為:pip3 install pillow,這里如果超時報錯的話,我們可以使用cch,
??然后我們創建一個captcha.py檔案用來存放生成隨機驗證碼的代碼,這里面captcha的意思是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自動區分計算機和人類的圖靈測驗)的縮寫,也就是我們俗稱的驗證碼,
??這里我們將隨機生成驗證碼的這個功能寫成一個類Captcha,然后我們通過這個類的方法來生成隨機圖片驗證碼,使用類進行封裝的話,可以對類內的部分私有方法進行封裝,提高安全性,下面我們就來一步一步的實作生成隨機驗證碼的各個功能,
??本文原創為CSDN博主亓官劼,原文鏈接為:小白都能看得懂的教程 看完這篇還不會生成隨機驗證碼圖片,你來打我!!!,請大家認準原創,
??我們本功能將會使用到3個庫,我們先進行匯入,
我們從PIL中匯入Image,ImageDraw,ImageFont:
import random
import string
from PIL import Image,ImageDraw,ImageFont
# 這里面Image是PIL中的畫布,ImageDraw是畫筆,ImageFont是畫筆的字體
設定我們類的一些基礎引數
??我們這里將生成隨機驗證碼寫成了一個Captcha類,下面我們來設定一些他的基礎引數,我們一般需要設定的有影像驗證碼的寬、高,驗證碼位數、干擾線條數量、驗證碼大小、然后我們還需要構建一個驗證碼字符的源檔案,這里各個部分在代碼中進行了詳細的注釋,我們邊看代碼邊看看注釋!
import random
import string
from PIL import Image, ImageDraw, ImageFont
# 這里面Image是PIL中的畫布,ImageDraw是畫筆,ImageFont是畫筆的字體
class Captcha(object):
# 生成隨機驗證碼的位數,可以根據需要進行修改
number = 4
# 干擾線條的條數
line_number = 2
# 生成驗證碼圖片的寬和高,可以根據需要進行修改
size = (100,40)
# 驗證碼字的大小,可以根據需要進行修改
fontsize = 24
# 建立驗證碼源文本
# list(string.ascii_letters) ASCII碼中所有的字母
SOURCE = list(string.ascii_letters)
# 再加入'0'到'9'
for index in range(10):
SOURCE.append(str(index))
生成隨機驗證碼文本
??這里生成隨機驗證碼的文本,我們只需要在SOURCE中隨機的選取number個字符即可,
# 生成驗證碼文本
@classmethod
def __gene_random_captcha(cls,number):
# number為驗證碼位數,回傳字串
return ''.join(random.sample(cls.SOURCE,number))
生成隨機字體
??這里我們來實作生成隨機字體的函式,因為同樣的字,不同的字體,他的形狀也是不一樣的,所以這里我們的字體也是采用隨機的,那么要生成隨機的字體,那么首先我們就要先要有字體的檔案,Windows下的字體檔案路徑為C/Windows/Fonts/,MacBook下的字體檔案路徑為/System/Library/Fonts/,如果找不到的話,可以看之前的一篇博文,內有詳細的介紹:在Windows下和MacBook中如何查找本地的字體檔案
??在找到我們的字體檔案之后,我們將它拖入到一個固定的檔案夾,便于我們后面去獲取這些字體檔案,這里由于我這邊是在之前OnlineForumPlatform專案中做的,所以這里將它放在了/static/font/檔案夾下,
??本文原創為CSDN博主亓官劼,原文鏈接為:小白都能看得懂的教程 看完這篇還不會生成隨機驗證碼圖片,你來打我!!!,請大家認準原創,

??下面我們來實作我們的隨機生成字體的函式,首先我們寫一個fonts串列,存放所有我們有的字體的檔案名稱,這里大家根據自己的字體檔案而定,代碼為:
# 生成隨機字體
@classmethod
def __generate_random_font(cls):
# 這里的fonts即是我們所有字體檔案的名稱,這里我是只復制過來了這么多,所以他的串列的這樣,大家根據自己他字體檔案來寫這個fonts
fonts = [
'Palatino.ttc',
'PingFang.ttc',
'STHeiti Light.ttc',
'STHeiti Medium.ttc',
'Thonburi.ttc',
'Times.ttc'
]
font = random.choice(fonts)
# 這里前面的字符為我們字符檔案的檔案夾位置
return '/static/font/'+font
生成隨機顏色
??這里由于我們是使用RGBA來表示顏色,所以我們在各個顏色的值的范圍為[0,255],我們這里可以設定默認的值為0和255,然后我們回傳3種顏色的亂數值即可;
# 生成隨機顏色
@classmethod
def __gene_random_color(cls,start=0,end=255):
# start為最小值,end為最大值,這里因為是RGB格式的,我們每個顏色的值最小為0,最大為255,所以這里默認為0和255
random.seed()
# 回傳3種顏色的值
return (random.randint(start,end),random.randint(start,end),random.randint(start,end))
生成隨機干擾線
??繪制干擾線可以讓我們的驗證碼不那么容易被軟體輕松的破解,添加他的干擾項,
# 繪制干擾線
@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(0,255),width=2)
生成隨機干擾點
??繪制干擾點可以讓我們的驗證碼不那么容易被軟體輕松的破解,添加他的干擾項,
# 繪制干擾點
@classmethod
def __gene_points(cls,draw,ponit_chance,width,height):
# chance為界限,如果當前亂數大于他,則繪制一個干擾電
chance = min(100,max(0,int(ponit_chance)))
# 遍歷圖
for i in range(height):
for j in range(width):
temp = random.randint(0,100)
if temp > chance:
# 繪制干擾點,第一個引數為位置,第二個引數為顏色
draw.point((j,i),fill = cls.__gene_random_color(0,255))
生成隨機圖片驗證碼
??在完成各個功能函式之后,最后我們來實作我們生成隨機圖片驗證碼的函式,這里我們邊看代碼邊解釋各個的原理,在代碼中進行了非常詳細的一個注釋說明,
??本文原創為CSDN博主亓官劼,原文鏈接為:小白都能看得懂的教程 看完這篇還不會生成隨機驗證碼圖片,你來打我!!!,請大家認準原創,
# 生成圖片驗證碼
@classmethod
def generate_graph_captcha(cls):
# 驗證碼圖片的寬和高,這里的size是我們上面進行設定的寬和高
width,height = cls.size
# 創建一個畫布
# 第一個引數為顏色的型別RGBA型,第二個引數為寬和高,第三個引數為顏色的值,這里呼叫__gene_random_color,這里我們引數顏色值可以自己進行修改
image = Image.new('RGBA',(width,height),cls.__gene_random_color(0,100))
# 設定驗證碼的字體
# 第一個引數為字體的值,即我們使用什么字體,我們呼叫生成隨機字體的函式,第二個引數為字體大小,在上面我們設定了默認值,可以進行修改
font = ImageFont.truetype(cls.__generate_random_font(),cls.fontsize)
# 創建畫筆,并且系結到上面創建的畫布image上
draw = ImageDraw.Draw(image)
# 生成隨機驗證碼文本,引數為驗證碼位數
captcha_str = cls.__gene_random_captcha(cls.number)
# 獲取字體的尺寸
font_width,font_height = font.getsize(captcha_str)
# 設定我們繪制的位置,這里為了驗證碼盡量在中間,我們選擇了中間點,大家可以根據需要進行修改
position = ((width - font_width)/2, (height - font_height)/2)
# 填充字串
# 第一個引數為繪制的位置,第二個引數為文本,這里使用生成的驗證碼文本,第三個引數為字體,第四個引數為文字的顏色
draw.text(position, captcha_str,font = font,fill = cls.__gene_random_color(150,255))
# 繪制干擾性
for i in range(cls.line_number):
cls.__gene_line(draw,width,height)
# 繪制干擾點
cls.__gene_points(draw,90,width,height)
# open的第一個引數的檔案名稱,在這里也可以在前面加上檔案夾的名,例如/static/captcha.png,第二個引數為打開方式
with open('captcha.png','wb') as fp:
image.save(fp)
return (captcha_str,image)
呼叫方法,生成隨機驗證碼
??到這里我們的功能已經完全的實作啦,然后我們只需要創建我們的物件,然后呼叫方法Captcha.generate_graph_captcha()即可在指定的位置生成我們的驗證碼影像,

全部原始碼
最后就是我們本功能的全部原始碼啦,如果不想碼代碼的話,可以直接拿過去用哦!
import random
import string
from PIL import Image, ImageDraw, ImageFont
# 這里面Image是PIL中的畫布,ImageDraw是畫筆,ImageFont是畫筆的字體
class Captcha(object):
# 生成隨機驗證碼的位數,可以根據需要進行修改
number = 4
# 干擾線條的條數
line_number = 2
# 生成驗證碼圖片的寬和高,可以根據需要進行修改
size = (100,40)
# 驗證碼字的大小,可以根據需要進行修改
fontsize = 24
# 建立驗證碼源文本
# list(string.ascii_letters) ASCII碼中所有的字母
SOURCE = list(string.ascii_letters)
# 再加入'0'到'9'
for index in range(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(0,255),width=2)
# 繪制干擾點
@classmethod
def __gene_points(cls,draw,ponit_chance,width,height):
# chance為界限,如果當前亂數大于他,則繪制一個干擾電
chance = min(100,max(0,int(ponit_chance)))
# 遍歷圖
for i in range(height):
for j in range(width):
temp = random.randint(0,100)
if temp > chance:# 繪制干擾點,第一個引數為位置,第二個引數為顏色draw.point((j,i),fill = cls.__gene_random_color(0,255))
# 生成驗證碼文本
@classmethod
def __gene_random_captcha(cls,number):
# number為驗證碼位數,回傳字串
return ''.join(random.sample(cls.SOURCE,number))
# 生成隨機字體
@classmethod
def __generate_random_font(cls):
# 這里的fonts即是我們所有字體檔案的名稱,這里我是只復制過來了這么多,所以他的串列的這樣,大家根據自己他字體檔案來寫這個fonts
fonts = [
'Palatino.ttc',
'PingFang.ttc',
'STHeiti Light.ttc',
'STHeiti Medium.ttc',
'Thonburi.ttc',
'Times.ttc'
]
font = random.choice(fonts)
# 這里前面的字符為我們字符檔案的檔案夾位置
return '/static/font/'+font
# 生成隨機顏色
@classmethod
def __gene_random_color(cls,start=0,end=255):
# start為最小值,end為最大值,這里因為是RGB格式的,我們每個顏色的值最小為0,最大為255,所以這里默認為0和255
random.seed()
# 回傳3種顏色的值
return (random.randint(start,end),random.randint(start,end),random.randint(start,end))
# 生成圖片驗證碼
@classmethod
def generate_graph_captcha(cls):
# 驗證碼圖片的寬和高,這里的size是我們上面進行設定的寬和高
width,height = cls.size
# 創建一個畫布
# 第一個引數為顏色的型別RGBA型,第二個引數為寬和高,第三個引數為顏色的值,這里呼叫__gene_random_color,這里我們引數顏色值可以自己進行修改
image = Image.new('RGBA',(width,height),cls.__gene_random_color(0,100))
# 設定驗證碼的字體
# 第一個引數為字體的值,即我們使用什么字體,我們呼叫生成隨機字體的函式,第二個引數為字體大小,在上面我們設定了默認值,可以進行修改
font = ImageFont.truetype(cls.__generate_random_font(),cls.fontsize)
# 創建畫筆,并且系結到上面創建的畫布image上
draw = ImageDraw.Draw(image)
# 生成隨機驗證碼文本,引數為驗證碼位數
captcha_str = cls.__gene_random_captcha(cls.number)
# 獲取字體的尺寸
font_width,font_height = font.getsize(captcha_str)
# 設定我們繪制的位置,這里為了驗證碼盡量在中間,我們選擇了中間點,大家可以根據需要進行修改
position = ((width - font_width)/2, (height - font_height)/2)
# 填充字串
# 第一個引數為繪制的位置,第二個引數為文本,這里使用生成的驗證碼文本,第三個引數為字體,第四個引數為文字的顏色
draw.text(position, captcha_str,font = font,fill = cls.__gene_random_color(150,255))
# 繪制干擾性
for i in range(cls.line_number):
cls.__gene_line(draw,width,height)
# 繪制干擾點
cls.__gene_points(draw,90,width,height)
# open的第一個引數的檔案名稱,在這里也可以在前面加上檔案夾的名,例如/static/captcha.png,第二個引數為打開方式
with open('captcha.png','wb') as fp:
image.save(fp)
return (captcha_str,image)
Captcha.generate_graph_captcha()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/73541.html
標籤:其他
