使用python,生成数字在图片上的验证码
许多网站在注册时都要求输入验证码,这样做为了防止被程序恶意注册和保证网站安全
1. Pillow
PIL(Python Imaging Library)
是一个强大的python图像处理库,只是支持到python2.7
, Pillow虽说是PIL的一个分支,但是pillow支持python3.x,已经发展成比PIL本身更具活力的图像处理库,我们使用Pillow来生成验证码,安装方式为
pip install Pillow
2. 生成一张指定大小随机颜色的图片
2.1 随机颜色
颜色的处理使用(r,g,b)格式,r, g, b 的范围是[0, 255], 使用random
模块的randint
方法生成3个随机数
def random_color():c1 = random.randint(0, 255)c2 = random.randint(0, 255)c3 = random.randint(0, 255)return c1, c2, c3
2.2 生成一张指定大小的图片
def random_color():c1 = random.randint(0, 255)c2 = random.randint(0, 255)c3 = random.randint(0, 255)return c1, c2, c3def generate_picture(width=120, height=35):image = Image.new('RGB', (width, height), random_color())return imageif __name__ == '__main__':image = generate_picture()image.save('test.png')
现在还只是生成了一张颜色随机的图片,接下来要在图片上面写上随机数字和字母
3. 在图片上写上随机数字和字母
3.1 生成随机数字和字母
def get_random_str():'''获取一个随机字符, 数字或小写字母:return:'''random_num = str(random.randint(0, 9))random_low_alpha = chr(random.randint(97, 122))random_char = random.choice([random_num, random_low_alpha])return random_char
使用random模块提供的随机函数生成指定长度的字符串
3.2 在image对象上画数字和字母
def draw_str(count, image, font_size):"""在图片上写随机字符:param count: 字符数量:param image: 图片对象:param font_size: 字体大小:return:"""draw = ImageDraw.Draw(image)# 获取一个font字体对象参数是ttf的字体文件的目录,以及字体的大小font_file = os.path.join('Andale Mono.ttf')font = ImageFont.truetype(font_file, size=font_size)temp = []for i in range(count):random_char = random_str()draw.text((10+i*30, -2), random_char, random_color(), font=font)temp.append(random_char)valid_str = "".join(temp) # 验证码return valid_str, imageif __name__ == '__main__':image = generate_picture()valid_str, image = draw_str(4, image, 35)image.save('test.png')
创建一个ImageDraw.Draw
对象,在image上画随机字符,你可以设置字体, 我使用了Andale Mono.ttf
, mac电脑上在/System/Library/Fonts
目录下找到字体,其他系统也有各自的字体文件,将字体文件复制到与脚本相同的目录下。
4. 制造噪点
为了防止验证码被轻易的破解,还应该在图片上制造一些噪点,随机画几条线,随机画几个点
def noise(image, width=120, height=35, line_count=3, point_count=20):''':param image: 图片对象:param width: 图片宽度:param height: 图片高度:param line_count: 线条数量:param point_count: 点的数量:return:'''draw = ImageDraw.Draw(image)for i in range(line_count):x1 = random.randint(0, width)x2 = random.randint(0, width)y1 = random.randint(0, height)y2 = random.randint(0, height)draw.line((x1, y1, x2, y2), fill=random_color())# 画点for i in range(point_count):draw.point([random.randint(0, width), random.randint(0, height)], fill=random_color())x = random.randint(0, width)y = random.randint(0, height)draw.arc((x, y, x + 4, y + 4), 0, 90, fill=random_color())return imageif __name__ == '__main__':image = generate_picture()valid_str, image = draw_str(4, image, 35)image = noise(image)image.save('test.png')
5. 生成base64编码的图片
实践中,如果是生成网站注册使用的验证码图片,一般来说不会将其保存到图片文件中,因为这会生成大量的小图片,完全没必要。我们可以将图片的内容保存到BytesIO
对象中,最终生成base64
编码的图片,这样,向前端传回去的就是字符串,格式为
data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAH...
data:image/jpeg;base64
这一段是固定写法,逗号剩余的部分是图片经过base64编码后的字符串
def valid_code():"""生成图片验证码,并对图片进行base64编码:return:"""image = generate_picture()valid_str, image = draw_str(4, image, 35)image = noise(image)f = BytesIO()image.save(f, 'png') # 保存到BytesIO对象中, 格式为pngdata = f.getvalue()f.close()encode_data = base64.b64encode(data)data = str(encode_data, encoding='utf-8')img_data = "data:image/jpeg;base64,{data}".format(data=data)return valid_str, img_dataif __name__ == '__main__':print(valid_code())
6. 全部代码
为了向你阐述生成验证码图片的过程,我将整个过程进行拆解,因此代码也被拆解的凌乱,你可以将这些代码整合,以便在实际应用中使用
import os
import random
import base64
from io import BytesIO
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFontdef random_color():c1 = random.randint(0, 255)c2 = random.randint(0, 255)c3 = random.randint(0, 255)return c1, c2, c3def generate_picture(width=120, height=35):image = Image.new('RGB', (width, height), random_color())return imagedef random_str():'''获取一个随机字符, 数字或小写字母:return:'''random_num = str(random.randint(0, 9))random_low_alpha = chr(random.randint(97, 122))random_char = random.choice([random_num, random_low_alpha])return random_chardef draw_str(count, image, font_size):"""在图片上写随机字符:param count: 字符数量:param image: 图片对象:param font_size: 字体大小:return:"""draw = ImageDraw.Draw(image)# 获取一个font字体对象参数是ttf的字体文件的目录,以及字体的大小font_file = os.path.join('Andale Mono.ttf')font = ImageFont.truetype(font_file, size=font_size)temp = []for i in range(count):random_char = random_str()draw.text((10+i*30, -2), random_char, random_color(), font=font)temp.append(random_char)valid_str = "".join(temp) # 验证码return valid_str, imagedef noise(image, width=120, height=35, line_count=3, point_count=20):''':param image: 图片对象:param width: 图片宽度:param height: 图片高度:param line_count: 线条数量:param point_count: 点的数量:return:'''draw = ImageDraw.Draw(image)for i in range(line_count):x1 = random.randint(0, width)x2 = random.randint(0, width)y1 = random.randint(0, height)y2 = random.randint(0, height)draw.line((x1, y1, x2, y2), fill=random_color())# 画点for i in range(point_count):draw.point([random.randint(0, width), random.randint(0, height)], fill=random_color())x = random.randint(0, width)y = random.randint(0, height)draw.arc((x, y, x + 4, y + 4), 0, 90, fill=random_color())return imagedef valid_code():"""生成图片验证码,并对图片进行base64编码:return:"""image = generate_picture()valid_str, image = draw_str(4, image, 35)image = noise(image)f = BytesIO()image.save(f, 'png') # 保存到BytesIO对象中, 格式为pngdata = f.getvalue()f.close()encode_data = base64.b64encode(data)data = str(encode_data, encoding='utf-8')img_data = "data:image/jpeg;base64,{data}".format(data=data)return valid_str, img_dataif __name__ == '__main__':print(valid_code())
相关文章:

使用python,生成数字在图片上的验证码
许多网站在注册时都要求输入验证码,这样做为了防止被程序恶意注册和保证网站安全 1. Pillow PIL(Python Imaging Library)是一个强大的python图像处理库,只是支持到python2.7, Pillow虽说是PIL的一个分支,但是pillow支持python3.xÿ…...

阿晨的运维笔记 | CentOS部署Docker
使用yum安装 # step 1: 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # Step 2: 添加软件源信息 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # Step 3: 更新并安装 …...

自动化运维:Ansible基础与命令行模块操作
目录 一、理论 1. Ansible 2.部署Ansible自动化运维工具 3.Ansible常用模块 4.hostsinverntory主机清单 二、实验 1.部署Ansible自动化运维工具 2.ansible 命令行模块 3.hostsinverntory主机清单 三、问题 1. ansible远程shell失败 2.组变量查看webservers内主机ip报…...

深度学习6:自然语言处理-Natural language processing | NLP
目录 NLP 为什么重要? 什么是自然语言处理 – NLP NLP 的2大核心任务 自然语言理解 – NLU|NLI 自然语言生成 – NLG NLP(自然语言处理) 的5个难点 NLP 的4个典型应用 NLP 的 2 种途径、3 个核心步骤 总结 自然语言处理 NLP 为什么重要? “语言…...
Mysql多表操作
文章目录 1. 概述2. 内连接3. 外连接4. 自连接5. 联合查询-union,union all6. 子查询 1. 概述 在项目开发中,在进行数据库表结构设计是,会根据业务需求和业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所…...

【leetcode 力扣刷题】数学题之计算次幂//次方:快速幂
利用乘法求解次幂问题—快速幂 50. Pow(x, n)372. 超级次方 50. Pow(x, n) 题目链接:50. Pow(x, n) 题目内容: 题目就是要求我们去实现计算x的n次方的功能函数,类似c的power()函数。但是我们不能使用power()函数直接得到答案,那…...

【核心复现】基于改进灰狼算法的并网交流微电网经济优化调度(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

Cannal监听binlog
文章目录 一、canal概念二、canal使用场景四、Canal工作原理Mysql主从复制原理 binlog中的二进制日志binlog格式选择 Canal消费方式应用实践总结 一、canal概念 canal是用java开发的基于数据库增量日志解析,提供增量数据订阅&消费的中间件。目前,ca…...

从零开发JavaWeb入门项目--十天掌握
原文网址:从零开发JavaWeb入门项目--十天掌握_IT利刃出鞘的博客-CSDN博客 简介 这是一个靠谱的JavaWeb入门项目实战,名字叫蚂蚁爱购。从零开发项目,视频加文档,十天就能学会开发JavaWeb项目,教程路线是:搭…...

数据结构——哈希表
哈希表 这里没有讲哈希表底层的概念,什么转红黑树,什么链表的,这篇文章主要讲的是如何用C实现哈希表,以及哈希表的基本概念。后面我会出一篇文章来讲C中hashmap中的底层逻辑的知识。 哈希表的概念 哈希表是一种数据结构࿰…...

Kafka3.0.0版本——手动调整分区副本示例
目录 一、服务器信息二、启动zookeeper和kafka集群2.1、先启动zookeeper集群2.2、再启动kafka集群 三、手动调整分区副本3.1、手动调整分区副本的前提条件3.2、手动调整分区副本的示例需求3.3、手动调整分区副本的示例 一、服务器信息 四台服务器 原始服务器名称原始服务器ip节…...
玩客云 线刷Armbian 搭配Alist 阿里云盘 Jellyfin NovaVideoPlayer搞电视墙
啰嗦的背景 喜欢看电影,买了个投影仪,是这一切折腾的开端。 投影仪虽然有当贝系统,但是想看的电影总是需要**电视会员,那我肯定是不用的。因为有爱腾优的会员,最开始都是使用手机投屏,当呗的投影仪好就好…...
9月1日,每日信息差
1、华大智造:已实现海外基因测序仪和测序试剂的量产,实现了海外基因测序仪和测序试剂的量产 2、邮储银行下调定存利率。价格表显示,整存整取,一年期存款年利率为1.58%,二年期年利率为1.85%,三年期年利率为…...

【大数据】Flink 详解(六):源码篇 Ⅰ
Flink 详解(六):源码篇 Ⅰ 55、Flink 作业的提交流程?56、Flink 作业提交分为几种方式?57、Flink JobGraph 是在什么时候生成的?58、那在 JobGraph 提交集群之前都经历哪些过程?59、看你提到 Pi…...

ShardingSphere——弹性伸缩原理
摘要 支持自定义分片算法,减少数据伸缩及迁移时的业务影响,提供一站式的通用弹性伸缩解决方案,是 Apache ShardingSphere 弹性伸缩的主要设计目标。对于使用单数据库运行的系统来说,如何安全简单地将数据迁移至水平分片的数据库上…...

Linux项目自动化构建工具-make/Makefile
一、什么是make和makefile make是一条指令 Makefile是当前目录下的一个文件 二、makefile文件编写 依赖关系::前为要目标文件,后为其依赖的文件 依赖方法:用依赖文件生成目标文件的具体指令 简便写法: $:表示目标文件 $^:表示…...
Python爬虫实战:自动化数据采集与分析
在大数据时代,数据采集与分析已经成为了许多行业的核心竞争力。Python作为一门广泛应用的编程语言,拥有丰富的爬虫库,使得我们能够轻松实现自动化数据采集与分析。本文将通过一个简单的示例,带您了解如何使用Python进行爬虫实战。…...

视频智能分析平台EasyCVR安防视频汇聚平台助力森林公园防火安全的应用方案
一、研发背景 随着经济的发展和人们生活水平的提高,越来越多的人喜欢在周末去周边的森林公园旅游,享受大自然的美景,并进行野炊和烧烤等娱乐活动。然而,近年来由于烟蒂和烧烤碳渣等人为因素,森林公园火灾频繁发生。森…...

跨境做独立站,如何低成本引流?
大家都知道,海外的消费习惯与国内不同,独立站一向是海外消费者的最喜欢的购物方式之一,这也吸引了许多跨境商家开设独立站。 独立站不同于其他的第三方平台,其他平台可以靠平台自身流量来获得转化,而独立站本身没有流…...

leetcode55.跳跃游戏 【贪心】
题目: 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 示例…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...