zoukankan      html  css  js  c++  java
  • python使用PIL模块随机生成验证码图片

    生成验证码图片首先需要字体文件(.TTF文件)

      免费获取字体文件地址:https://www.zijia.com.cn/FindFont.html 

     

     1.随机生成颜色

    import random
    import os
    import time
    
    def get_random_color():
        """
        随机生成颜色
        :return:
        """
        return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))

    2.将生成的图片文件保存在本地

    from PIL import Image, ImageDraw, ImageFont
    from CRM01 import settings
    
    def get_verification_img():
        """
        生成验证码图片
        :return: 返回图片路径
        """
        # Image图片处理,ImageDraw给图片上画东西,ImageFont处理图片上文字
    
        # RGB采取那种颜色的标准,RGB,RGBA、等. 第二个参数代表图片大小高度宽度,第三个随机颜色
        img_obj = Image.new('RGB', (200, 34), get_random_color())
    
        draw_obj = ImageDraw.Draw(img_obj)  # 通过图片对象生成一个画笔对象
    
        font_path = os.path.join(settings.BASE_DIR, 'statics/static/font/FZZJ-HGXSJW.TTF')  # static/font/FZQuSJW.TTF字体文件  字体文件存放路径
        # 获取字体、注意有些字体文件不能识别数字,所有数字显示不出来,就换一个字体
        font_obj = ImageFont.truetype(font_path, 25)  # 16字体大小。 创建一个字体对象
    
        sum_str = ''  # 这个数据就是用户需要输入的验证码的内容
    
        for i in range(6):
            a = random.choice(
                [str(random.randint(0, 9)), chr(random.randint(97, 122)), chr(random.randint(65, 90))])  # chr将sicii的数值转换成英文
            sum_str += a
        print(sum_str)
        draw_obj.text((64, 10), sum_str, fill=get_random_color(), font=font_obj)  # 通过画笔对象,添加文字以及颜色
        # (64,10)起始画的坐标点,sum_str随机生成字符串,fill背景颜色,font字体
    
        # 添加噪线噪点
        width = 200
        height = 34
        # 添加噪线
        for i in range(5):  # 添加5个噪线
            # 一个坐标表示一个点,两个点就可以连成一条线
            x1 = random.randint(0, width)
            x2 = random.randint(0, width)
            y1 = random.randint(0, height)
            y2 = random.randint(0, height)
            draw_obj.line((x1, y1, x2, y2), fill=get_random_color())
        # 添加噪点
        for i in range(20):  # 添加20个噪点
            draw_obj.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color())
            # 下面是添加很小的弧线,看上去类似于一个点,40个小弧线
            x = random.randint(0, width)
            y = random.randint(0, height)
            draw_obj.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())  # x,y是弧线的起始点位置,x+4,y+4是弧线的结束位置
    
        verification_path = os.path.join(settings.BASE_DIR, 'statics/verification_img/')
        # 保存文件路径、已经文件名称
        img_name = verification_path + f'{time.time()}.png'
        img_obj.save(img_name)  # 可以将图片保存在本地
        return img_name

    3.如果我们不想将生成的文件保存在本地的话,我们可以在内存中重新开辟一块空间,保存在内存中。然后我们从内存中取,这样也不会每次都会生成一个图片验证吗,浪费资源。下面是直接使用接口封装,如果需要其他处理自行拆分封装。

    #获取验证码接口
    def get_valid_img(request):
        import random
        import os
        def get_random_color():
            return (random.randint(0,255),random.randint(0,255),random.randint(0,255))
        from PIL import Image,ImageDraw,ImageFont
        #Image图片处理,ImageDraw给图片上画东西,ImageFont处理图片上文字
    
        #RGB采取那种颜色的标准,RGB,RGBA、等. 第二个参数代表图片大小高度宽度,第三个随机颜色
        img_obj = Image.new('RGB',(200,34),get_random_color())
    
        draw_obj = ImageDraw.Draw(img_obj)#通过图片对象生成一个画笔对象
    
        from supercrm import settings
        font_path = os.path.join(settings.BASE_DIR,'static/font/NAUERT_.TTF') #static/font/NAUERT_.TTF字体文件
        #获取字体、注意有些字体文件不能识别数字,所有数字显示不出来,就换一个字体
        font_obj = ImageFont.truetype(font_path,16) #16字体大小。 创建一个字体对象
    
        sum_str = ''  #这个数据就是用户需要输入的验证码的内容
    
        for i in range(6):
            a = random.choice([str(random.randint(0,9)),chr(random.randint(97,122)),chr(random.randint(65,90))]) #chr将sicii的数值转换成英文
            sum_str += a
        print(sum_str)
        draw_obj.text((64,10),sum_str,fill=get_random_color(),font=font_obj) #通过画笔对象,添加文字以及颜色
        #(64,10)起始画的坐标点,sum_str随机生成字符串,fill背景颜色,font字体
    
    
        #添加噪线噪点
        width = 200
        height = 34
        #添加噪线
        for i in range(5): #添加5个噪线
            #一个坐标表示一个点,两个点就可以连成一条线
            x1 = random.randint(0,width)
            x2 = random.randint(0,width)
            y1 = random.randint(0,height)
            y2 = random.randint(0,height)
            draw_obj.line((x1,y1,x2,y2),fill=get_random_color())
        #添加噪点
        for i in range(40): #添加40个噪点
            draw_obj.point([random.randint(0,width),random.randint(0,height)],fill=get_random_color())
            #下面是添加很小的弧线,看上去类似于一个点,40个小弧线
            x = random.randint(0,width)
            y = random.randint(0,height)
            draw_obj.arc((x,y,x+4,y+4),0,90,fill=get_random_color()) #x,y是弧线的起始点位置,x+4,y+4是弧线的结束位置
    
    
        #现阶段图片已经生成但是不在本地而是在内存中,因此我们需要在内存中将图片存在本地。下面就要使用到io模块的BytesIO(字节流)
        from io import BytesIO
        f = BytesIO()
        img_obj.save(f,'png') #以png格式将图片保存在BytesIO中。相当于在内存中开了一块空间,将图片以png格式存储
        data = f.getvalue() #从临时空间中取出数据
        request.session['valid_str'] = sum_str
        return HttpResponse(data)
  • 相关阅读:
    JavaScript实现继承机制(4)——构造函数+原型链混合方式
    NodeJS”热部署“代码,实现动态调试
    初识NodeJS,一个基于GoogleV8引擎的Javascript运行环境
    那些你不得不知道的JavaScript 变量命名规则
    JavaScript声明全局变量的三种方式
    JavaScript实现继承机制(3)——通过原型链(prototype chaining)方式
    JavaScript实现继承机制(1)—— 构造函数方法对象冒充
    C# readonly和const
    C# winform增加界面动态加载的流畅性
    C# 正确操作字符串,规避字符串转换所带来的额外开销
  • 原文地址:https://www.cnblogs.com/zhuxibo/p/14754488.html
Copyright © 2011-2022 走看看