Python生成验证码(可画干扰线、噪点)

1.写作由来

  最近练习做一个电商项目,在注册页面准备加一个验证码功能。之前虽然也写过一个简单的验证码生成函数,但如今来看,真是有些‘勉强’,于是结合网上的一些文章,重新改良了一番。

2.实现思路

  2.1制作验证码,我们首先得把验证码所必须的元素搞清楚。下面是我认为必需的一些参数。

参数名参数含义
width生成图片的宽度
height生成图片的高度
bgColor生成图片的背景色
num验证码字符个数
fontPath字体路径
fontSize字体大小
code验证码内容(作为返回值,用于验证)
img生成图片对象
savePath生成图片的保存路径

  2.2弄清楚参数,还要考虑下验证码的呈现方式。如:字符随机产生、颜色随机更换、字符位置随机改变、干扰线的数量、噪点的数量…考虑清楚这些,便可以着手敲代码了。

3.代码实现

# coding:utf-8
import random
import os
import string
import json
from PIL import Image, ImageDraw, ImageFont

# 将随机函数赋给变量 rdint
rdint = random.randint

class vertifyCode():
    def __init__(self, width, height, bgColor, num, fontPath, fontSize, savePath):
        self.width = width  # 生成图片宽度
        self.height = height  # 生成图片高度
        self.bgColor = bgColor  # 生成图片背景颜色
        self.num = num  # 验证码字符个数
        self.fontPath = fontPath  # 字体路径
        self.fontSzie = fontSize  # 字体大小
        self.code = ''  # 验证内容
        self.img = Image.new('RGB', (self.width, self.height), self.bgColor)  # 生成图片对象
        self.savePath = savePath #生成图片的保存路径

    # 获取随机颜色,RGB格式
    def get_random_Color(self):
        c1 = rdint(50, 150)
        c2 = rdint(50, 150)
        c3 = rdint(50, 150)
        return (c1, c2, c3)

    # 随机生成1位字符,作为验证码内容
    def get_random_char(self):
        c = ''.join(random.sample(string.ascii_letters + string.digits, 1))
        self.code += c
        return c

    # 生成随机位置(x,y)
    def get_random_xy(self):
        x = rdint(0, int(self.width))
        y = rdint(0, int(self.height))
        return (x, y)

    # 根据字体文件生成字体,无字体文件则生成默认字体
    def get_font(self):
        if self.fontPath:
            if os.path.exists(self.fontPath):
                if self.fontSzie and self.fontSzie > 0 and self.fontSzie < self.height:
                    size = self.fontSzie
                else:
                    size = rdint(int(self.height /1.5), int(self.height - 10))
                font = ImageFont.truetype(self.fontPath, size)
                return font
            raise Exception('字体文件不存在或路径错误', self.fontPath)
        return ImageFont.load_default().font

    # 图片旋转
    def rotate(self):
        deg = int(self.height / 3)  # 旋转角度
        self.img = self.img.rotate(rdint(0, deg), expand=0)

    # 画n条干扰线
    def drawLine(self, n):
        draw = ImageDraw.Draw(self.img)
        for i in range(n):
            draw.line([self.get_random_xy(), self.get_random_xy()],
                      self.get_random_Color())
        del draw

    # 画n个干扰点
    def drawPoint(self, n):
        draw = ImageDraw.Draw(self.img)
        for i in range(n):
            draw.point([self.get_random_xy()], self.get_random_Color())
        del draw

    # 写验证码内容
    def drawText(self, position, char, fillColor):
        draw = ImageDraw.Draw(self.img)
        draw.text(position, char, font=self.get_font(), fill=fillColor)
        del draw

    # 生成验证码图片,并返回图片对象
    def getVertifyImg(self):
        x_start = 2
        y_start = 0
        for i in range(self.num):
            x = x_start + i * int(self.width / (self.num))
            y = rdint(y_start, int(self.height / 3))
            self.drawText((x, y), self.get_random_char(),
                          self.get_random_Color())
        self.drawLine(3)
        self.drawPoint(60)
        return self.img

    # 将图片保存到内存,便于前台点击刷新
    # 将验证码保存到session中,返回内存中的图片数据
    def saveInMemory(self, request):
        img = self.getVertifyImg()
        request.session['code'] = self.code.lower()
        f = BytesIO()  # 开辟内存空间
        img.save(f, 'png')
        return f.getvalue()

    # 将图片保存在本地,并以json格式返回验证码内容
    def saveInLocal(self):
        img = self.getVertifyImg()
        try:
            img.save(self.savePath)
        except:
            raise NotADirectoryError('保存路径错误或不存在:' + self.savePath)
        return json.dumps({'code': self.code})

4.效果图

        

博主其他文章推荐:
[1] 【python实用特性】- 迭代、可迭代对象、迭代器

[2] 【python实用特性】- 列表生成式

[3] 【python实用特性】- yield生成器

[4] 【python实用特性】- 装饰器

[5] 【Matplotlib】-自定义坐标轴刻度完成20万+数据的可视化

[6] Python+selenium实现自动爬取实例

[7] python爬取豆瓣Top250-改进版

[8] requests使用cookie模拟登陆豆瓣

[9] requests使用session保持会话

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
您好!对于Python的图像处理,可以使用OpenCV库来实现干扰线噪点的去除。下面是一个简单的示例代码,演示了如何使用OpenCV去除图像干扰线噪点: ```python import cv2 def remove_noise(image): # 灰度化 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 值滤波去噪 denoised = cv2.medianBlur(gray, 5) # 边缘检测 edges = cv2.Canny(denoised, 50, 150) # 轮廓检测 contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 去除小面积轮廓 for contour in contours: area = cv2.contourArea(contour) if area < 100: cv2.drawContours(edges, [contour], -1, 0, thickness=cv2.FILLED) # 根据边缘图像去除干扰线 result = cv2.bitwise_and(image, image, mask=edges) return result # 读取图像 image = cv2.imread('image.jpg') # 去除干扰线噪点 result = remove_noise(image) # 显示结果 cv2.imshow('Original Image', image) cv2.imshow('Result', result) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在代码,首先将彩色图像转换为灰度图像,然后使用值滤波进行去噪处理。接下来,使用Canny边缘检测算法检测图像的边缘,并通过轮廓检测找到边缘轮廓。然后,对于面积较小的轮廓,使用`cv2.drawContours`函数将其填充为黑色,以去除这些干扰线。最后,使用`cv2.bitwise_and`函数根据边缘图像去除干扰线,并得到最终结果。 请注意,代码使用的参数值可能需要根据具体情况进行调整,以达到最佳的去除效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值