Python案例如何生成验证码图片?

wen python案例 2

本文目录导读:

Python案例如何生成验证码图片?

  1. 方法1:使用 captcha 库(最简单)
  2. 方法2:使用 Pillow 库自定义(推荐)
  3. 方法3:交互式验证码生成器
  4. 方法4:将验证码保存为字节流(用于Web应用)
  5. 使用建议

我来介绍几种在Python中生成验证码图片的方法:

方法1:使用 captcha 库(最简单)

# 首先安装:pip install captcha
from captcha.image import ImageCaptcha
import random
import string
def generate_captcha_captcha():
    """使用captcha库生成验证码"""
    # 创建ImageCaptcha对象
    image = ImageCaptcha(width=200, height=80, fonts=['Arial.ttf'])
    # 生成随机验证码(4位数字+字母组合)
    captcha_text = ''.join(random.choices(string.ascii_uppercase + string.digits, k=4))
    # 生成图片
    image.write(captcha_text, 'captcha_simple.png')
    # 或者直接获取图片数据
    data = image.generate(captcha_text)
    print(f"验证码文字: {captcha_text}")
    return captcha_text
# 使用示例
generate_captcha_captcha()

方法2:使用 Pillow 库自定义(推荐)

# 首先安装:pip install Pillow
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
import string
class CaptchaGenerator:
    def __init__(self, width=200, height=80):
        self.width = width
        self.height = height
        self.font_size = 40
    def generate_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 generate_text(self, length=4):
        """生成随机验证码文本"""
        chars = string.ascii_uppercase + string.digits
        return ''.join(random.choice(chars) for _ in range(length))
    def create_captcha_image(self, text=None):
        """创建验证码图片"""
        if text is None:
            text = self.generate_text()
        # 创建空白图片
        image = Image.new('RGB', (self.width, self.height), 
                         self.generate_random_color(200, 255))
        draw = ImageDraw.Draw(image)
        # 加载字体(如果没有中文字体,使用默认字体)
        try:
            font = ImageFont.truetype("arial.ttf", self.font_size)
        except:
            font = ImageFont.load_default()
        # 绘制验证码文字
        for i, char in enumerate(text):
            # 随机旋转角度
            angle = random.randint(-30, 30)
            # 创建单个字符的图片
            char_image = Image.new('RGBA', (self.font_size, self.font_size), (0, 0, 0, 0))
            char_draw = ImageDraw.Draw(char_image)
            char_draw.text((0, 0), char, font=font, 
                          fill=self.generate_random_color(0, 100))
            # 旋转字符
            rotated_char = char_image.rotate(angle, expand=1)
            # 计算位置
            x = 20 + i * 45
            y = 10 + random.randint(-5, 10)
            # 粘贴到主图片
            image.paste(rotated_char, (x, y), rotated_char)
            # 添加随机噪点
            for _ in range(5):
                if random.random() > 0.5:
                    noise_color = self.generate_random_color(150, 255)
                    draw.line([
                        (random.randint(0, self.width), random.randint(0, self.height)),
                        (random.randint(0, self.width), random.randint(0, self.height))
                    ], fill=noise_color, width=2)
        # 添加干扰线
        for _ in range(3):
            line_color = self.generate_random_color(100, 200)
            start_point = (random.randint(0, self.width), random.randint(0, self.height))
            end_point = (random.randint(0, self.width), random.randint(0, self.height))
            draw.line([start_point, end_point], fill=line_color, width=2)
        # 添加滤镜增加难度
        image = image.filter(ImageFilter.SMOOTH_MORE)
        return image, text
    def save_captcha(self, filename="captcha.png"):
        """生成并保存验证码"""
        image, text = self.create_captcha_image()
        image.save(filename)
        print(f"验证码已保存到: {filename}")
        print(f"验证码文字: {text}")
        return text
# 使用示例
generator = CaptchaGenerator()
text = generator.save_captcha("my_captcha.png")

方法3:交互式验证码生成器

import tkinter as tk
from PIL import Image, ImageTk, ImageDraw, ImageFont
import random
import string
class CaptchaApp:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("验证码生成器")
        self.root.geometry("400x300")
        self.captcha_text = ""
        self.setup_ui()
        self.generate_new_captcha()
    def setup_ui(self):
        # 显示验证码的标签
        self.captcha_label = tk.Label(self.root)
        self.captcha_label.pack(pady=20)
        # 输入框
        self.entry = tk.Entry(self.root, font=("Arial", 14))
        self.entry.pack(pady=10)
        # 按钮
        btn_frame = tk.Frame(self.root)
        btn_frame.pack(pady=10)
        tk.Button(btn_frame, text="刷新验证码", 
                 command=self.generate_new_captcha).pack(side=tk.LEFT, padx=5)
        tk.Button(btn_frame, text="验证", 
                 command=self.verify_captcha).pack(side=tk.LEFT, padx=5)
        # 结果显示
        self.result_label = tk.Label(self.root, text="", font=("Arial", 12))
        self.result_label.pack(pady=10)
    def generate_captcha(self):
        """生成验证码图片"""
        width, height = 200, 80
        image = Image.new('RGB', (width, height), (240, 240, 240))
        draw = ImageDraw.Draw(image)
        # 生成随机文本
        chars = string.ascii_uppercase + string.digits
        self.captcha_text = ''.join(random.choice(chars) for _ in range(4))
        # 尝试加载字体
        try:
            font = ImageFont.truetype("arial.ttf", 40)
        except:
            font = ImageFont.load_default()
        # 绘制文字
        for i, char in enumerate(self.captcha_text):
            x = 20 + i * 45
            y = 10 + random.randint(-5, 10)
            color = (random.randint(0, 100), 
                    random.randint(0, 100), 
                    random.randint(0, 100))
            draw.text((x, y), char, font=font, fill=color)
        # 添加干扰线
        for _ in range(3):
            x1 = random.randint(0, width)
            y1 = random.randint(0, height)
            x2 = random.randint(0, width)
            y2 = random.randint(0, height)
            draw.line([(x1, y1), (x2, y2)], 
                     fill=(random.randint(0, 255), 
                          random.randint(0, 255), 
                          random.randint(0, 255)), 
                     width=2)
        return image
    def generate_new_captcha(self):
        """生成新的验证码"""
        image = self.generate_captcha()
        photo = ImageTk.PhotoImage(image)
        self.captcha_label.config(image=photo)
        self.captcha_label.image = photo
        self.entry.delete(0, tk.END)
        self.result_label.config(text="")
    def verify_captcha(self):
        """验证输入"""
        user_input = self.entry.get().upper()
        if user_input == self.captcha_text:
            self.result_label.config(text="✓ 验证成功!", fg="green")
        else:
            self.result_label.config(text="✗ 验证失败,请重试", fg="red")
    def run(self):
        self.root.mainloop()
# 使用示例
app = CaptchaApp()
app.run()

方法4:将验证码保存为字节流(用于Web应用)

from PIL import Image, ImageDraw, ImageFont
import random
import string
import io
def generate_captcha_bytes():
    """生成验证码并返回字节流"""
    width, height = 200, 80
    # 创建图片
    image = Image.new('RGB', (width, height), (255, 255, 255))
    draw = ImageDraw.Draw(image)
    # 生成随机文本
    chars = string.ascii_uppercase + string.digits
    captcha_text = ''.join(random.choice(chars) for _ in range(4))
    # 绘制文字
    for i, char in enumerate(captcha_text):
        color = (random.randint(0, 100), 
                random.randint(0, 100), 
                random.randint(0, 100))
        draw.text((20 + i * 45, 20), char, fill=color)
    # 保存为字节流
    buffer = io.BytesIO()
    image.save(buffer, format='PNG')
    buffer.seek(0)
    return buffer.getvalue(), captcha_text
# 使用示例
image_bytes, text = generate_captcha_bytes()
print(f"验证码文字: {text}")
print(f"图片大小: {len(image_bytes)} 字节")

使用建议

  1. 简单需求:使用 captcha 库,一行代码即可生成
  2. 自定义样式:使用 Pillow 自定义颜色、字体、干扰线等
  3. Web应用:生成字节流返回给前端
  4. 安全性考虑
    • 验证码有效期(建议5分钟内)
    • 验证后立即销毁
    • 限制验证尝试次数
    • 避免使用简单可预测的模式

这些示例涵盖了从简单到复杂的不同场景,你可以根据具体需求选择合适的方法。

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