Python生成中文图形验证码的脚本

注:此脚本非原创,只是在原作者代码基础上做了一点点调整。原创链接https://www.cnblogs.com/whu-zeng/p/4855480.html

网上许多生成中文验证码的脚本都不能用,要么python解释器版本过旧,要么各种不明bug。两个小时终于找到了一个合适的。下面分享一下:

# -*- coding: utf-8 -*-

import codecs
import random
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
import math, string
from django.utils.six import unichr


class RandomChar():
    @staticmethod
    def Unicode():
        val = random.randint(0x4E00, 0x9FBF)
        return unichr(val)

    @staticmethod
    def GB2312():
        head = random.randint(0xB0, 0xCF)
        body = random.randint(0xA, 0xF)
        tail = random.randint(0, 0xF)
        val = (head << 8) | (body << 4) | tail
        str = "%x" % val
        #   return str.decode('hex').decode('gb2312')
        # return str.encode('gb2312').decode('gb2312')
        return codecs.decode(str, 'hex_codec').decode('gb2312')


class ImageChar():
    def __init__(self, fontColor=(0, 0, 0),
                 size=(150, 60),
                 # fontPath='C:/Windows/Fonts/wqy.ttc',
                 fontPath='C:/Windows/Fonts/simsun.ttc',
                 bgColor=(255, 255, 255),
                 fontSize=25):
        self.size = size
        self.fontPath = fontPath
        self.bgColor = bgColor
        self.fontSize = fontSize
        self.fontColor = fontColor
        self.font = ImageFont.truetype(self.fontPath, self.fontSize)
        self.image = Image.new('RGB', size, bgColor)
        self.char_list = []

    def rotate(self):
        self.image.rotate(random.randint(0, 30), expand=0)

    def drawText(self, pos, txt, fill):
        draw = ImageDraw.Draw(self.image)
        #  print(pos)
        # print(txt)
        # print(self.font)
        # print(fill)
        draw.text(pos, txt, font=self.font, fill=fill)
        del draw

    def randRGB(self):
        return (random.randint(0, 255),
                random.randint(0, 255),
                random.randint(0, 255))

    def randPoint(self):
        (width, height) = self.size
        return (random.randint(0, width), random.randint(0, height))

    def randLine(self, num):
        draw = ImageDraw.Draw(self.image)
        for i in range(0, num):
            draw.line([self.randPoint(), self.randPoint()], self.randRGB())
        del draw

    def randChinese(self, num):
        gap = 5
        start = 0
        char_list = []
        while True:
            try:
                for i in range(0, num):
                    char_list.append(RandomChar().GB2312())
                    x = start + self.fontSize * i + random.randint(0, gap) + gap * i
                    self.drawText((x, random.randint(-5, 5)), char_list[-1], self.randRGB())
                    self.rotate()
                self.randLine(18)
                self.char_list = char_list
                break
            except:
                continue

    def output(self):
        output_buffer = BytesIO()
        self.image.save(output_buffer, format='JPEG')
        byte_data = output_buffer.getvalue()
        return byte_data
        

def generate_code():
    ic = ImageChar(fontColor=(100, 211, 90))
    ic.randChinese(4)
    byte_data = ic.output()
    chars = ''.join(ic.char_list)
    return (byte_data, chars)


if __name__ == '__main__':
    generate_code()

调用generate_code函数即可获得图片验证码的二进制流和对应的汉字内容。

但是!
我的脚本有个问题:
下面这段代码的try语句很奇怪吧?因为在我运行脚本的过程中发现,某些特定范围的汉字生成时会出bug。也没时间去找原因,因此为了应急,才用了try语句(偶尔失败一次,那就重新生成呗)。日后闲下来了,我会再来研究研究的。

def randChinese(self, num):
        gap = 5
        start = 0
        char_list = []
        while True:
            try:
                for i in range(0, num):
                    char_list.append(RandomChar().GB2312())
                    x = start + self.fontSize * i + random.randint(0, gap) + gap * i
                    self.drawText((x, random.randint(-5, 5)), char_list[-1], self.randRGB())
                    self.rotate()
                self.randLine(18)
                self.char_list = char_list
                break
            except:
                continue

再次注:此脚本非原创,只是在原作者代码基础上做了一点点调整。原创链接https://www.cnblogs.com/whu-zeng/p/4855480.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,生成随机图形验证码通常涉及到图像处理库,如PIL(Python Imaging Library)或其更新版本Pillow,以及可能用到的随机数生成库如random和numpy。以下是一个简单的步骤概述: 1. 导入所需的库: ```python from PIL import Image, ImageDraw, ImageFont import random import numpy as np ``` 2. 定义图形元素,如线条、圆形、矩形、字母和数字: ```python def draw_random_shape(size, shapes): shape = random.choice(shapes) if shape == 'line': draw.line((random.randint(0, size), random.randint(0, size)), (random.randint(0, size), random.randint(0, size)), fill=(0, 0, 0)) elif shape == 'circle': center = (random.randint(0, size), random.randint(0, size)) draw.ellipse((center-10, center-10, center+10, center+10), fill=(0, 0, 0)) # 添加其他形状,如矩形等 def generate_text(): return ''.join(random.choices('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', k=random.randint(4, 6))) ``` 3. 创建验证码图像: ```python size = 100 image = Image.new('RGB', (size, size), color='white') draw = ImageDraw.Draw(image) shapes = ['line', 'circle', 'rectangle'] # 可自定义形状列表 for _ in range(random.randint(4, 6)): draw_random_shape(size, shapes) text = generate_text() font = ImageFont.truetype("arial.ttf", size=random.randint(20, 30)) # 加载字体 text_position = (random.randint(10, size-10), random.randint(10, size-10)) draw.text(text_position, text, font=font, fill=(0, 0, 0)) # 保存验证码图片 image.save('captcha.png') ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值