首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python PIL/Pillow 生成圖片驗證碼:文字繪製、扭曲變形、干擾線與保存

     編輯:更多程式設計知識

安裝


pip install pillow

完整生成流程


from PIL import Image, ImageDraw, ImageFont
import random, math

# 畫布設置
width, height = 120, 40
bgcolor = (255, 255, 255)
image = Image.new('RGB', (width, height), bgcolor)

# 字體(需確保字體文件存在)
try:
    font = ImageFont.truetype('DejaVuSans.ttf', 28)
except:
    font = ImageFont.load_default()

fontcolor = (0, 0, 0)
draw = ImageDraw.Draw(image)

# 生成隨機驗證碼
code = ''.join(random.choices('ABCDEFGHJKLMNPQRSTUVWXYZ23456789', k=4))
draw.text((10, 5), code, font=font, fill=fontcolor)

# 釋放 draw(繪製扭曲前需重建)
del draw

# 扭曲變形
new_image = Image.new('RGB', (width, height), bgcolor)
new_pix = new_image.load()
pix = image.load()
offset = 0
for y in range(height):
    offset += 1
    for x in range(width):
        new_x = x + offset
        # 正弦波扭曲:new_x = x + math.sin(y/10)*10
        if new_x < width:
            new_pix[new_x, y] = pix[x, y]

# 仿射變形
new_image = new_image.transform((width+20, height+10), Image.AFFINE, (1, -0.3, 0, -0.1, 1, 0))

# 干擾線
draw = ImageDraw.Draw(new_image)
line_color = (0, 0, 0)
for _ in range(8):
    x1, x2 = random.randint(0, width), random.randint(0, width)
    y1, y2 = random.randint(0, height), random.randint(0, height)
    draw.line([(x1, y1), (x2, y2)], fill=line_color)

# 保存
new_image.save('captcha.png')
print(f'驗證碼: {code}')

關鍵技術點

  • 字體:生產環境請打包 TTF 字體,避免系統缺失;
  • 字符集:排除易混淆字符(O/0, I/1, l/1);
  • 扭曲:像素偏移或 Image.AFFINE 仿射變換;
  • 干擾線/點:適量即可,過多影響用戶識別;
  • Session 存儲:驗證碼需存入 Session/Redis,驗證時比對並刪除。

Flask 集成示例


from flask import Flask, session, send_file
from io import BytesIO

app = Flask(__name__)
app.secret_key = 'your_secret'

@app.route('/captcha')
def captcha():
    img, code = generate_captcha()  # 返回 Image 對象與字符串
    session['captcha'] = code.lower()
    buf = BytesIO()
    img.save(buf, 'PNG')
    buf.seek(0)
    return send_file(buf, mimetype='image/png')

@app.route('/verify', methods=['POST'])
def verify():
    if request.form.get('captcha', '').lower() == session.pop('captcha', ''):
        return 'OK'
    return 'FAIL', 400
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved