pillow实例 | 生成随机验证码
1 PIL(Python Image Library)
PIL是Python进行基本图片处理的package,囊括了诸如图片的剪裁、缩放、写入文字等功能。现在,我便以生成随机验证码为例,讲述PIL的基本用法。
PIL库似乎已经被人抛弃,就为更新,上次使用时竟然不能用show()直接将图片,在系统默认的图片管理器中打开。好在pillow,一个PIL的方言,将PIL继续维护了下去。
生成验证码一般需要对写入的文字进行旋转、扭曲、变色等一系列操作,才能避免计算机算法的识别。
因此定义一个生成验证码的类是一个不错的选择,旋转、扭曲、变色就作为这个类的一系列方法。
2 初始化Captcha类
Captcha是Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的图灵测试)的简称,是世界上最为著名的验证码项目,后来被google受够,现在它们开始用图片以外的其他方式来区分人与计算机
初始化需要设置验证码图片的大小、以及字体的大小,默认已选择了比较合适的值。
需要用到Draw子包的new方法新建一张图片,要给定mode、size和color。这就像是现实画画中的幕布。
mode与不同的图片表示格式有关,
彩色图片是可以通过红R、绿G、蓝B三原色合成而来,存储在计算机里的便是3个矩阵,这种最常见的模式叫做'RGB';
黑白图片则只需要一层,用'1'表示;
在计算机屏幕显示的彩色图片在三原色的基础上,进而出现一个透明层,表示能够透过多少下一层图片,这种模式叫做'RGBA',A代指alpha。
from PIL import Image class Captcha(object):
def __init__(self,size=(100,40),fontSize=30):
self.font = ImageFont.truetype('C:\Windows\Fonts\Arial.ttf',fontSize)
self.size = size
self.image = Image.new('RGBA',self.size,(255,)*4)
self.texts = self.randNum(5)
ImageFont包用于处理字体,需要具体给定使用字体的路径以及字体的大小,Windows系统下字都在C:\Windows\Fonts\路径下。
3 生成随机的数字及颜色
随机数字
使用random包的randint(start,end)方法,随机产生0~9中的一个数字,需要注意的是包含start和end
def randNum(self,bits):
return ''.join(str(random.randint(0,9)) for i in range(bits))
随机颜色
颜色一般用8位表示,十进制下便是0~255的一个整数,随机生成一个三元组即可
def randColor(self):
self.fontColor = (random.randint(0,250),random.randint(0,250),random.randint(0,250))
这都非常简单
4 写入文字
写入文字需要用到ImageDraw包
def write(self,text,x):
draw = ImageDraw.Draw(self.image)
draw.text((x,4),text,fill=self.fontColor,font=self.font)
text方法需要指定,写入文字的位置,以左上角为原点,当然以像素为单位;写入的文字;写入文字的颜色;最后说字体
5 旋转文字
旋转一般不是直接旋转文字,而是旋转幕布,在这里需要随机旋转一个角度。
旋转幕布会产生一个问题,旋转后边边角角会伸到画板的外面,而最终我们需要一个方方正正的验证码图片。
伸到画板外面的幕布需要剪裁掉,因为旋转空余的地方又需要补上。
Image.composite(img1,img2,img1)就可以解决这个问题,它会把img1透明/空白的地方,用img2补上。在这里应该是纯白的背景。
def rotate(self):
rot = self.image.rotate(random.randint(-10,10),expand=0) #默认为0,表示剪裁掉伸到画板外面的部分
fff = Image.new('RGBA',rot.size,(255,)*4)
self.image = Image.composite(rot,fff,rot)
6 形成验证码
有了上面的方法作铺垫,以一定的间隔,写上几个数字,就得到验证码了
def writeNum(self):
x = 10
xplus = 15
for text in self.texts:
self.randColor()
self.write(text, x)
self.rotate()
x += xplus
return self.texts
此方法会返回验证码的文字,这样计算机才能判断人是否输入正确。不像上面的几个方法,这个方法是面向用户的。
最终的效果是这样子的aaarticlea/jpeg;base64,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" alt="" /> aaarticlea/jpeg;base64,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" alt="" />
附:完整的代码
class Captcha(object):
def __init__(self,size=(100,40),fontSize=30):
self.font = ImageFont.truetype('C:\Windows\Fonts\Arial.ttf',fontSize)
self.size = size
self.image = Image.new('RGBA',self.size,(255,)*4)
self.texts = self.randNum(5) def rotate(self):
rot = self.image.rotate(random.randint(-10,10),expand=0)
fff = Image.new('RGBA',rot.size,(255,)*4)
self.image = Image.composite(rot,fff,rot) def randColor(self):
self.fontColor = (random.randint(0,250),random.randint(0,250),random.randint(0,250)) def randNum(self,bits):
return ''.join(str(random.randint(0,9)) for i in range(bits)) def write(self,text,x):
draw = ImageDraw.Draw(self.image)
draw.text((x,4),text,fill=self.fontColor,font=self.font) def writeNum(self):
x = 10
xplus = 15
for text in self.texts:
self.randColor()
self.write(text, x)
self.rotate()
x += xplus
return self.texts def save(self):
self.image.save('captcha.jpg') img = Captcha()
num = img.writeNum()
#img.image.show()
#img.save()
pillow实例 | 生成随机验证码的更多相关文章
- 基于Python Pillow库生成随机验证码
from PIL import Image from PIL import ImageDraw from PIL import ImageFont import random class ValidC ...
- Django中生成随机验证码(pillow模块的使用)
Django中生成随机验证码 1.html中a标签的设置 <img src="/get_validcode_img/" alt=""> 2.view ...
- Python 生成随机验证码
Python生成随机验证码 Python生成随机验证码,需要使用PIL模块. 安装: 1 pip3 install pillow 基本使用 1. 创建图片 1 2 3 4 5 6 7 8 9 fro ...
- Python生成随机验证码
Python生成随机验证码,需要使用PIL模块. 安装: pip3 install pillow 基本使用 1.创建图片 from PIL import Image img = Image.new(m ...
- Python使用PIL模块生成随机验证码
PIL模块的安装 pip3 install pillow 生成随机验证码图片 import random from PIL import Image, ImageDraw, ImageFont fro ...
- Java生成随机验证码
package com.tg.snail.core.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphic ...
- C#生成随机验证码例子
C#生成随机验证码例子: 前端: <tr> <td width=" align="center" valign="top"> ...
- struts2生成随机验证码图片
之前想做一个随机验证码的功能,自己也搜索了一下别人写的代码,然后自己重新用struts2实现了一下,现在将我自己实现代码贴出来!大家有什么意见都可以指出来! 首先是生成随机验证码图片的action: ...
- Python利用PIL生成随机验证码图片
安装pillow: pip install pillow PIL中的Image等模块提供了创建图片,制作图片的功能,大致的步骤就是我们利用random生成6个随机字符串,然后利用PIL将字符串绘制城图 ...
随机推荐
- jquery实现奇偶行赋值不同css值
<html> <head> <title>jquery奇偶行css效果</title> <script src="../../jquer ...
- noip模拟赛 但有用
题目描述 给定一个 n ∗ m 个矩阵,矩阵中每个数都是 [1, 12] 内的整数.你可以执行下列两个操作任意多次: • 指定一行,将该行所有数字 +1. • 指定一列,将该列所有数字 +1. 如果执 ...
- springboot集成junit测试与javamail测试遇到的问题
1.springboot如何集成junit测试? 导入junit的jar包 使用下面注解: @RunWith()关于这个的解释看下这两篇文章: http://www.imooc.com/qadetai ...
- python练习:抓取统计log内ip数量
#!/usr/bin/python #-*- coding: utf- -*- import os import re rawfile = '/var/log/auth.log' def rawpar ...
- 解决在linux安装网易云音乐无法点击图标打开
一下内容转载自:https://blog.csdn.net/Handoking/article/details/81026651 似乎linux下无法直接打开网易云音乐的原因是图标自带的启动脚本中没有 ...
- [Luogu 1963] NOI2009 变换序列
[Luogu 1963] NOI2009 变换序列 先%Dalao's Blog 什么?二分图匹配?这个确定可以建图? 「没有建不成图的图论题,只有你想不出的建模方法.」 建图相当玄学,不过理解大约也 ...
- Item 3 ------单例模式的几种实现方式,及优缺点
单例模式,是指一个类只有一个唯一的实例,一个类只会被实例化一次.实现这种效果,最佳的方式,编写包含单个元素的枚举类型. 单例模式的最佳实现方式-----创建一个包含单个元素的枚举类 public en ...
- 【bzoj2038-小z的袜子】莫队算法
莫队例题. 莫队学习:https://www.cnblogs.com/Paul-Guderian/p/6933799.html 本题 分子是sigma(c(sum[a[i]],2)),分母是sigma ...
- 【BZOJ2850】巧克力王国 [KD-tree]
巧克力王国 Time Limit: 60 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description 巧克力王国里的巧克力都是由牛奶和 ...
- 【NOI】2004 郁闷的出纳员
[算法]平衡树(treap) [题解] treap知识见数据结构. 解法,具体细节见程序. #include<cstdio> #include<algorithm> #incl ...