PIL基础操作

新建图片

from PIL import Image

# 通常使用RGB模式就可以了
new_img = Image.new('RGB', (100, 100), 'red')
new_img.save("1.jpg", "JPEG") new_img = Image.new('RGB', (100, 100), '#B286FF')
new_img.save("2.jpg", "JPEG") new_img = Image.new('RGB', (100, 100), (255, 255, 128))
new_img.save("3.jpg", "JPEG")

打开图片

BASE_PATH = os.path.dirname(os.path.abspath(__file__))

file_path = os.path.join(BASE_PATH, "fj.jpg")

# 打开图片
img = Image.open(file_path) """
format : 识别图像的源格式,如果该文件不是从文件中读取的,则被置为 None 值。
size : 返回的一个元组,有两个元素,其值为象素意义上的宽和高。
mode :
· 1 (1-bit pixels, black and white, stored with one pixel per byte)
· L (8-bit pixels, black and white)
· P (8-bit pixels, mapped to any other mode using a colour palette)
· RGB (3x8-bit pixels, true colour)
· RGBA (4x8-bit pixels, true colour with transparency mask)
· CMYK (4x8-bit pixels, colour separation)
· YCbCr (3x8-bit pixels, colour video format)
· I (32-bit signed integer pixels)
· F (32-bit floating point pixels)
""" print img.format, img.size, img.mode, img.height, img.width
# h,w = img.size # (X,Y)
等价于
# h = img.heigth
# w = img.width # 缩略图
img.thumbnail((w*0.75, h//2))
img.save("1.jpg", "JPEG") # 应用模糊滤镜:
im2 = img.filter(ImageFilter.BLUR)
# 存储图片
im2.save('blur.jpg', 'JPEG')
• BLUR:模糊滤波
• CONTOUR:轮廓滤波
• DETAIL:细节滤波
• EDGE_ENHANCE:边界增强滤波
• EDGE_ENHANCE_MORE:边界增强滤波(程度更深)
• EMBOSS:浮雕滤波
• FIND_EDGES:寻找边界滤波
• SMOOTH:平滑滤波
• SMOOTH_MORE:平滑滤波(程度更深)
• SHARPEN:锐化滤波
• GaussianBlur(radius=2):高斯模糊
>radius指定平滑半径。
• UnsharpMask(radius=2, percent=150, threshold=3):反锐化掩码滤波
>radius指定模糊半径;
>percent指定反锐化强度(百分比);
>threshold控制被锐化的最小亮度变化。
• Kernel(size, kernel, scale=None, offset=0):核滤波
当前版本只支持核大小为3x3和5x5的核大小,且图像格式为“L”和“RGB”的图像。
>size指定核大小(width, height);
>kernel指定核权值的序列;
>scale指定缩放因子;
>offset指定偏移量,如果使用,则将该值加到缩放后的结果上。
• RankFilter(size, rank):排序滤波
>size指定滤波核的大小;
>rank指定选取排在第rank位的像素,若大小为0,则为最小值滤波;若大小为size * size / 2则为中值滤波;若大小为size *
size - 1则为最大值滤波。
• MedianFilter(size=3):中值滤波
>size指定核的大小
• MinFilter(size=3):最小值滤波器
>size指定核的大小
• MaxFilter(size=3):最大值滤波器
>size指定核的大小
• ModeFilter(size=3):波形滤波器
选取核内出现频次最高的像素值作为该点像素值,仅出现一次或两次的像素将被忽略,若没有像素出现两次以上,则保留原像素值。
>size指定核的大小

ImageFilter类预定义滤波

裁切图片

在这个副本上的任何操作不会影响到原图像

# 接收元组(X,Y,X,Y)
cp_img = img.crop((0, 100, 30, 300))
cp_img.save("cp.jpg", "JPEG")

复制图片

# 剪切
# cp_img = img.crop((0, 0, 450, 300))
# 复制
cp_img = img.copy()
# 新建图片
new_img = Image.new("RGB", (500, 300), (255, 255, 255))
# 在新建的图片上粘贴裁剪的图片
# new_img.paste(cp_img)
# 指定起始坐标(左上角)
new_img.paste(cp_img, (50, 0))
new_img.save("cp_img.jpg", "JPEG")

调整图片大小

resize不是等比例缩放的

w,d = img. size
# 只接受整数
new_img = img.resize((500, 350))
new_img.save("1.jpg", "JPEG")

旋转图片

# 90度
img.rotate(90).save("rotate90.jpg", "JPEG")
# 180度
img.rotate(180).save("rotate180.jpg", "JPEG")
# 270度
img.rotate(270).save("rotate270.jpg", "JPEG")
# 20度
img.rotate(20).save("rotate20.jpg", "JPEG")
# 放大旋转20度,expand放大了图像尺寸,使得边角的图像不被裁剪四个角刚好贴着图像边缘)
img.rotate(20, expand=True).save("20.jpg", "JPEG")
# 图像的镜面翻转(必须传入Image.FLIP_LEFT_RIGHT(水平翻转)/Image.FLIP_TOP_BOTTOM(垂直翻转))
img.transpose(Image.FLIP_LEFT_RIGHT).save("tran_img.jpg", "JPEG") # 水平翻转
img.transpose(Image.FLIP_TOP_BOTTOM).save("tran_img_.jpg", "JPEG") # 垂直翻转

画图(ImageDraw)

导入包

from PIL import ImageDraw
from PIL import Image

直线

# 新建画板
im_board = Image.new("RGB", (500, 500), (255, 255, 255))
# 创建画笔(所有画的动作都是由此对象生成的)
drawObject = ImageDraw.Draw(im_board) # 起始xy,结束xy[x,y,x,y] fill直线颜色 width直线宽度
drawObject.line([150, 50, 350, 50], fill=10, width=5)
drawObject.line([(150, 250), 350, 250], fill=128)
drawObject.line([(150, 50), (150, 250)], "black")
drawObject.line((350, 50, 350, 250), fill="yellow")

 效果:

# fill颜色为将圆填充色, outline边界颜色
drawObject.arc((150, 200, 300, 350), 0, 360, fill="black")
drawObject.arc((150, 220, 300, 350), 180, 360, fill="red")
drawObject.arc((150, 230, 300, 350), 180, 270, fill="red")
drawObject.arc((150, 235, 300, 350), 270, 180, fill="red")
drawObject.arc((150, 240, 300, 350), 180, 270, fill="red")
drawObject.arc((150, 245, 300, 350), 270, 180, fill="red") # fill颜色为将圆填充色, outline边界颜色
# drawObject.ellipse((150, 200, 300, 350), fill="blue", outline=128)

 效果:

# 用法与arc相同,用来画圆从startAngle到endAngle的弦
# Options选项中fill表示将弦与圆弧之间空间用指定颜色填满,outlie表示只规定弦线的颜色
# drawObject.chord([x1, y1, x2, y2], startAngle, endAngle, options) # 画圆
drawObject.ellipse((100, 100, 300, 300), outline=128) # 画弦并且将弦与弧包围区域涂色
drawObject.chord((100, 100, 300, 300), 0, 360, fill="yellow") # 画一条弦
drawObject.chord((100, 100, 300, 300), 0, 180, outline="blue")
drawObject.chord((100, 100, 300, 300), 0, 135, outline="blue")
drawObject.chord((100, 100, 300, 300), 135, 270, outline="blue")
drawObject.chord((100, 100, 300, 300), 270, 45, outline="blue")
drawObject.chord((100, 100, 300, 300), 45, 180, outline="blue")

 效果:

扇区

# options选项中fill选项将扇形区域用指定颜色填满,outline选项只用指定颜色描出区域轮廓
# drawObject.pieslice([x1,y1,x2,y2], startAngle, endAngle, options)
# 画一个圆
drawObject.ellipse((100, 100, 300, 300), outline=128)
# 画180度到210度的扇形区域轮廓
drawObject.pieslice((100, 100, 300, 300), 0, 45, outline=128)
drawObject.pieslice((100, 100, 300, 300), 180, 235, outline=128) # 画60度到90度的扇形区域
drawObject.pieslice((100, 100, 300, 300), 0, 90, fill="blue")
drawObject.pieslice((100, 100, 300, 300), 180, 270, fill="blue")

 效果:

多边形

# 根据第一个参量中的xy坐标对,连接出整个图形
# options选项中fill选项将多边形区域用指定颜色填满,outline选项只用指定颜色描出区域轮廓
# drawObject.polygon(([x1,y1,x2,y2,…],options)
# 第一点坐标 第二点坐标 第三点坐标 连接线的颜色
drawObject.polygon([(50, 300), (200, 300), (50, 100)], outline="red")
drawObject.polygon([(50, 100), (300, 100), (50, 300), (300, 300)], fill="red", outline="blue")
drawObject.polygon([(50, 100), (50, 300), (300, 100), (300, 300)], fill="blue", outline="red")

 效果:

矩形

# (x1,y1)表示矩形左上角坐标值,(x2,y2)表示矩形右下角坐标值
# options选项中fill选项将多边形区域用指定颜色填满,outline选项只用指定颜色描出区域轮廓
# drawObject.rectangle([x1,y1,x2,y2],options)drawObject
drawObject.rectangle((100, 100, 300, 300), outline="red")
drawObject.rectangle((100, 300, 300, 320), fill=128)

 效果:

添加文字

# Position是一个二元元组,指定字符串左上角坐标,string是要写入的字符串
# options选项可以为fill或者font(只能选择其中之一作为第三参量.
# 不能两个同同时存在,要改变字体颜色,见ImageFont模块
# text = u"人生苦短,我用派生"
text = u"I Love You"
drawObject.text([100, 200], text, "red")

 效果:

在图片中写字

from PIL import ImageDraw, ImageFont
from PIL import Image hwxw_path = os.path.join(BASE_PATH, "font", "华文新魏.ttf")
hwxk_path = os.path.join(BASE_PATH, "font", "华文行楷.ttf")
hwls_path = os.path.join(BASE_PATH, "font", "华文隶书.ttf")
# 新建画板
im_board = Image.new("RGB", (500, 500), (255, 255, 255))
# 画笔对象
drawObject = ImageDraw.Draw(im_board)
# 定义字体 ImageFont.truetype(file,size)
# 创建一个字体对象.这个函数从指定的文件加载了一个字体对象,并且为指定字体大小
hwxw_font = ImageFont.truetype(hwxw_path, 18)
hwxk_font = ImageFont.truetype(hwxk_path, 24)
hwls_font = ImageFont.truetype(hwls_path, 36)
"""
注意事项:笔的默认颜色为白色,画笔的颜色可以通过draw的ink属性来改变
draw.ink = 0(R) + 0(G) * 256 + 0(B) * 256 * 256
也可以通过fill参数更改字体颜色
""" drawObject.rectangle([100, 100, 400, 400], outline=128) text = u"人生苦短"
text_ = u"我用"
text__ = u"Python"
# 利用text函数添加文字
# drawObject.ink = 0 + 0 * 256 + 0 * 256 * 256
drawObject.text([180, 170], text, font=hwxw_font, fill="yellow")
# drawObject.ink = 0 + 128 + 100
drawObject.text([180, 200], text_, font=hwxk_font, fill="blue")
# drawObject.ink = 0 + 0 * 256 + 255 * 256 * 256
drawObject.text([180, 230], text__, font=hwls_font, fill=(255, 222, 111)) im_board.save("drawing_board.png", "PNG") # Font.getsize(text)
# 返回一个二元素元组,为指定text在指定字体大小之后的size
print hwxk_font.getsize(text)

生成验证码(借鉴):

import Image, ImageDraw, ImageFont, ImageFilter
import random hwxw_path = os.path.join(BASE_PATH, "font", "华文新魏.ttf")
hwxk_path = os.path.join(BASE_PATH, "font", "华文行楷.ttf")
hwls_path = os.path.join(BASE_PATH, "font", "华文隶书.ttf")
font_list = [hwxw_path, hwxk_path, hwls_path] # 随机字母:
def rndChar():
return chr(random.randint(65, 90)) # 随机颜色1:
def rndColor():
return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255)) # 随机颜色2:
def rndColor2():
return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127)) # 240 x 60:
width = 60 * 4
height = 60
image = Image.new('RGB', (width, height), (255, 255, 255))
# 创建Font对象:
font = ImageFont.truetype(random.choice(font_list), 36)
# 创建Draw对象:
draw = ImageDraw.Draw(image)
# 填充每个像素:
for x in range(width):
for y in range(height):
draw.point((x, y), fill=rndColor())
# 输出文字:
for t in range(4):
draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2())
# 模糊:
image = image.filter(ImageFilter.BLUR)
image.save('code.jpg', 'jpeg')

Pillow只是个基础的图像处理库,OpenCV是更好的选择

PIL基础操作的更多相关文章

  1. python基础操作以及hdfs操作

    目录 前言 基础操作 hdfs操作 总结 一.前言        作为一个全栈工程师,必须要熟练掌握各种语言...HelloWorld.最近就被"逼着"走向了python开发之路, ...

  2. MYSQL基础操作

    MYSQL基础操作 [TOC] 1.基本定义 1.1.关系型数据库系统 关系型数据库系统是建立在关系模型上的数据库系统 什么是关系模型呢? 1.数据结构可以规定,同类数据结构一致,就是一个二维的表格 ...

  3. 【Learning Python】【第二章】Python基础类型和基础操作

    基础类型: 整型: py 3.0解决了整数溢出的问题,意味着整型不必考虑32位,64位,有无符号等问题,你写一个1亿亿亿,就是1亿亿亿,不会溢出 a = 10 ** 240 print(a) 执行以上 ...

  4. Emacs学习心得之 基础操作

    作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Emacs学习心得之 基础操作 1.前言与学习计划2.Emacs基础操作 一. 前言与学习计 ...

  5. Git基础操作

    配置秘钥 1.检查本机有没有秘钥 检查~/.ssh看看是否有名为d_rsa.pub和id_dsa.pub的2个文件. $ ~/.sshbash: /c/Users/lenovo/.ssh: Is a ...

  6. activiti基础操作

    package activitiTest; import java.io.InputStream; import java.util.List; import java.util.zip.ZipInp ...

  7. 《Genesis-3D开源游戏引擎-官方录制系列视频教程:基础操作篇》

    注:本系列教程仅针对引擎编辑器:v1.2.2及以下版本 G3D基础操作   第一课<G3D编辑器初探> G3D编辑器介绍,依托于一个复杂场景,讲解了场景视图及其基本操作,属性面板和工具栏的 ...

  8. MYSQL 基础操作

    1.MySQL基础操作 一:MySQL基础操作 1:MySQL表复制 复制表结构 + 复制表数据 create table t3 like t1; --创建一个和t1一样的表,用like(表结构也一样 ...

  9. php之文件基础操作

    在php中对文件的基础操作非常的简单,php提供的函数粗略的用了一遍. file_get_contents():可以获取文件的内容获取一个网络资源的内容,这是php给我封装的一个比较快捷的读取文件的内 ...

随机推荐

  1. P2P流媒体开源项目介绍

    P2P流媒体开源项目介绍1. PeerCast 2002年成立,最早的开源P2P流媒体项目.PeerCast把节点按树结构组织起来, 每个频道都是一个树, 直播源是根节点,父节点只给子节点提供数据.节 ...

  2. 使用Visual Studio进行单元测试-Shim类中无法找到参数包含CancellationTokenSource的方法

    Shim类中无法找到参数包含CancellationTokenSource的方法,这句话有点绕口,看例子. 一.代码 public class CancellationDemo { public in ...

  3. TextBlock截断字符显示为....

    添加: TextTrimming="CharacterEllipsis" 到TextBlock中, 即可让TextBlock 支持截断字符显示为...

  4. poj 2000 Gold Coins(水题)

    一.Description The king pays his loyal knight in gold coins. On the first day of his service, the kni ...

  5. vue 给嵌套的iframe子页面传数据 postMessage

    Vue组件下嵌套了一个不同域下的子页面,iframe子页面不能直接获取到父页面的数据,即使数据存在localStorage中,子页面一样是获取不到的,所以只好使用postMessage传数据: < ...

  6. QTP连接数据库

    '注意:其中DSN=数据源名:UID=用户名:PWD=用户密码 Dim Conn Set Conn=CreateObject("ADODB.Connection") Const C ...

  7. linux日常管理-防火墙netfilter工具-iptables-2

    分别是包的数量:26  包的字节:1320  处理方式 tcp协议  opt in out  源ip 目标ip 到80端口的行为. 处理行为处理有REJECT外 还有DROP ACCEPT.分别是看一 ...

  8. Ubuntu 切换root用户是时出现su Authentication failure

    su root 时出现错误su Authentication failure 原因是没有给root用户设置密码 sudo passwd root

  9. AlteraFPGA使用通用SPIFlash - 张亚群的技术专栏 - 博客频道 - CSDN.NET

    AlteraFPGA使用通用SPIFlash - 张亚群的技术专栏 - 博客频道 - CSDN.NET Altera器件有EPCS系列配置器件,其实,这些配置器件就是我们平时通用的SPIFlash,据 ...

  10. [51nod1272]最大距离(贪心)

    解题关键:对num进行排序,从前往后扫id,及时更新 #include<cstdio> #include<cstring> #include<algorithm> ...