怎样实现图片验证码生成脚本

wen 实用脚本 19

本文目录导读:

怎样实现图片验证码生成脚本

  1. 方法一:使用 Pillow 库(推荐)
  2. 方法二:使用 captcha 库(最简单)
  3. 方法三:高级版本(带更多干扰)
  4. 方法四:带扭曲效果的验证码
  5. 安装依赖
  6. 在Web应用中使用(Flask示例)
  7. 注意事项

我来为你提供几种实现图片验证码生成的方法,从简单到复杂:

使用 Pillow 库(推荐)

from PIL import Image, ImageDraw, ImageFont
import random
import string
def generate_captcha(width=200, height=80, length=4):
    """
    生成图片验证码
    """
    # 创建画布
    image = Image.new('RGB', (width, height), color='white')
    draw = ImageDraw.Draw(image)
    # 生成验证码文本
    captcha_text = ''.join(random.choices(string.digits + string.ascii_uppercase, k=length))
    # 添加干扰点
    for _ in range(random.randint(50, 100)):
        x = random.randint(0, width)
        y = random.randint(0, height)
        draw.point((x, y), fill=random_color())
    # 添加干扰线
    for _ in range(random.randint(3, 5)):
        x1, y1 = random.randint(0, width), random.randint(0, height)
        x2, y2 = random.randint(0, width), random.randint(0, height)
        draw.line((x1, y1, x2, y2), fill=random_color(), width=2)
    # 写入文字
    for i, char in enumerate(captcha_text):
        # 随机字体大小和颜色
        font_size = random.randint(30, 45)
        font = ImageFont.truetype("arial.ttf", font_size)
        # 计算位置,让字符分布在画布上
        x = 20 + i * (width // length)
        y = random.randint(5, height - font_size - 5)
        # 随机旋转字符
        char_image = Image.new('RGBA', (font_size, font_size))
        char_draw = ImageDraw.Draw(char_image)
        char_draw.text((0, 0), char, fill=random_color(), font=font)
        # 旋转
        rotated_char = char_image.rotate(random.randint(-30, 30), expand=1)
        # 粘贴到主图上
        image.paste(rotated_char, (x, y), rotated_char)
    return image, captcha_text
def random_color():
    """生成随机颜色"""
    return (random.randint(50, 200), random.randint(50, 200), random.randint(50, 200))
# 使用示例
if __name__ == "__main__":
    captcha_image, captcha_text = generate_captcha()
    captcha_image.save("captcha.png")
    print(f"验证码文本: {captcha_text}")

使用 captcha 库(最简单)

from captcha.image import ImageCaptcha
import random
import string
def generate_captcha_simple(length=4):
    """
    使用captcha库生成验证码
    """
    # 创建验证码生成器
    image = ImageCaptcha(width=200, height=80, fonts=['arial.ttf'])
    # 生成验证码文本
    captcha_text = ''.join(random.choices(string.digits + string.ascii_uppercase, k=length))
    # 生成图片
    data = image.generate(captcha_text)
    # 保存图片
    image.write(captcha_text, 'captcha_simple.png')
    return captcha_text
# 使用示例
print(f"验证码文本: {generate_captcha_simple()}")

高级版本(带更多干扰)

from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
import string
import numpy as np
class AdvancedCaptcha:
    def __init__(self, width=240, height=80):
        self.width = width
        self.height = height
        self.image = None
        self.draw = None
    def generate(self, length=4):
        """生成高级验证码"""
        # 创建背景
        self.image = Image.new('RGB', (self.width, self.height), 
                               color=self._random_bg_color())
        self.draw = ImageDraw.Draw(self.image)
        # 生成验证码文本
        captcha_text = ''.join(random.choices(string.ascii_uppercase + string.digits, k=length))
        # 添加各种干扰
        self._add_noise()
        self._add_lines()
        self._add_text(captcha_text)
        self._add_distortion()
        # 添加滤镜效果
        self.image = self.image.filter(ImageFilter.SMOOTH_MORE)
        return self.image, captcha_text
    def _random_bg_color(self):
        """生成随机背景色"""
        return (random.randint(200, 255), 
                random.randint(200, 255), 
                random.randint(200, 255))
    def _random_color(self, min_val=50, max_val=200):
        """生成随机颜色"""
        return (random.randint(min_val, max_val),
                random.randint(min_val, max_val),
                random.randint(min_val, max_val))
    def _add_noise(self):
        """添加噪点"""
        for _ in range(random.randint(300, 500)):
            x = random.randint(0, self.width - 1)
            y = random.randint(0, self.height - 1)
            self.draw.point((x, y), fill=self._random_color())
    def _add_lines(self):
        """添加干扰线"""
        for _ in range(random.randint(3, 6)):
            x1 = random.randint(0, self.width // 2)
            y1 = random.randint(0, self.height)
            x2 = random.randint(self.width // 2, self.width)
            y2 = random.randint(0, self.height)
            self.draw.line(
                [(x1, y1), (x2, y2)], 
                fill=self._random_color(100, 180), 
                width=random.randint(1, 3)
            )
    def _add_text(self, text):
        """添加文字"""
        try:
            font = ImageFont.truetype("arial.ttf", random.randint(35, 50))
        except:
            font = ImageFont.load_default()
        for i, char in enumerate(text):
            # 计算位置
            x = 15 + i * (self.width // len(text))
            y = random.randint(5, 15)
            # 创建字符图片
            char_img = Image.new('RGBA', (60, 60), (0, 0, 0, 0))
            char_draw = ImageDraw.Draw(char_img)
            # 绘制字符
            char_draw.text((5, 5), char, fill=self._random_color(), font=font)
            # 随机旋转
            angle = random.randint(-25, 25)
            rotated_img = char_img.rotate(angle, expand=1, fillcolor=(0, 0, 0, 0))
            # 粘贴到主图
            self.image.paste(rotated_img, (x, y), rotated_img)
    def _add_distortion(self):
        """添加扭曲效果"""
        # 使用简单的水波纹效果
        self.image = self.image.transform(
            self.image.size,
            Image.MESH,
            [(0, 0, self.width, self.height, 0, random.randint(-5, 5))],
            resample=Image.BILINEAR
        )
# 使用示例
if __name__ == "__main__":
    captcha_generator = AdvancedCaptcha()
    img, text = captcha_generator.generate()
    img.save("advanced_captcha.png")
    print(f"验证码文本: {text}")

带扭曲效果的验证码

from PIL import Image, ImageDraw, ImageFont
import random
import math
def generate_distorted_captcha():
    width, height = 200, 80
    image = Image.new('RGB', (width, height), (255, 255, 255))
    draw = ImageDraw.Draw(image)
    # 生成验证码
    chars = ''.join(random.choices('ABCDEFGHJKLMNPQRSTUVWXYZ23456789', k=4))
    # 添加波浪扭曲
    for x in range(width):
        for y in range(height):
            # 计算偏移
            offset_x = int(10 * math.sin(2 * math.pi * y / height * 2))
            offset_y = int(10 * math.cos(2 * math.pi * x / width * 3))
            new_x = (x + offset_x) % width
            new_y = (y + offset_y) % height
            pixel = image.getpixel((x, y))
            # 这里简化处理,实际应用中需要更复杂的图像变换
    # 写入字符
    for i, char in enumerate(chars):
        font = ImageFont.truetype("arial.ttf", 36)
        x = 20 + i * 45
        y = random.randint(10, 30)
        draw.text((x, y), char, fill=random_color(), font=font)
    return image, chars
def random_color():
    return (random.randint(0, 150), random.randint(0, 150), random.randint(0, 150))

安装依赖

# 基础版本需要的库
pip install Pillow
# 如果使用方法二
pip install captcha
# 如果使用方法三(可选)
pip install numpy

在Web应用中使用(Flask示例)

from flask import Flask, session, make_response
from io import BytesIO
app = Flask(__name__)
app.secret_key = 'your-secret-key'
@app.route('/captcha')
def get_captcha():
    # 生成验证码
    captcha_image, captcha_text = generate_captcha()
    # 保存到session
    session['captcha'] = captcha_text
    # 转换为响应
    buf = BytesIO()
    captcha_image.save(buf, 'PNG')
    buf.seek(0)
    response = make_response(buf.getvalue())
    response.headers['Content-Type'] = 'image/png'
    return response
@app.route('/verify', methods=['POST'])
def verify_captcha():
    user_input = request.form['captcha']
    if user_input.upper() == session.get('captcha', '').upper():
        return '验证成功!'
    return '验证失败!'

注意事项

  1. 字体文件:确保系统有 arial.ttf 字体,或者指定其他可用字体
  2. 验证码安全:避免使用容易被机器识别的简单字体和颜色
  3. 性能优化:生产环境建议使用缓存机制
  4. 存储:验证码文本通常存储在 session 或 redis 中

选择哪种方法取决于你的具体需求:

  • 简单快速 → 方法一(Pillow)
  • 最易实现 → 方法二(captcha库)
  • 需要更多定制 → 方法三(高级版本)

抱歉,评论功能暂时关闭!