今天我是一个 lsp,分享二次元老婆的第一天
前言
学习不就是看个人兴趣的嘛!!!
某年某月某天在家无聊翻看社区,乍一看一张冰冰姐的美图出现在了眼前,看见人家把冰冰姐的图片处理的漂漂亮亮,我终于按捺不住自己那 lsp (不不不,错了,是激动)的心,赶紧把图像处理学了起来,那废话少说,来学习吧!!!放心,我也是零基础,讲的内容保证百分比易懂,哈哈哈哈!!!好羞涩
加载、显示、保存图片
此处我们得先导入一个库 PIL,但是很不幸,这是 Python 2. 版本才具备的库,但是 Python 3. 岂能就此止步,它也有一个相应的库 pillow
我们导入的方法是在命令行(window + R 运行 cmd 启动命令行)中输入:pip install pillow -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
切记:我们在 Python 3. 版本中书写库的名称时,仍然要使用 PIL 哦!
从基础开始,我们只需要导入 PIL 库中的 Image 模块, from PIL import Image
对了,还一个更重要的,我们还需要准备一个图片,此处我给大家准备一个(小蕾姆.jpg
)
接下来,开始正式的编码时光,新建工程项目(pythonProject),右键工程项目创建新的文件夹(PIL),右键 PIL 文件夹创建次级新的文件夹(images),右键 PIL 创建一个新的 python 文件(part1.py)
part1.py
文件代码如下:
from PIL import Image
# 1. 加载图片
photo1 = Image.open("小蕾姆.jpg")
# 2. 显示图片
photo1.show()
# 3. 保存图片
photo1.save("images\\Beautiful.jpg")
代码运行过程中,首先调用电脑默认的图片显示器显示一次图片,然后将图片保存在 images 文件夹下(我们自定义图片名字为 Beautiful.jpg
)
是不是很激动了,感觉又发现了新大陆,接下来让我们更深层次的去学习 PIL
滤镜效果
谁还不喜欢滤镜这个东西呢!?反正作者我是对这玩意挺感兴趣的,想起曾经天天对着手机摆弄这些滤镜效果的样子,不寒而栗,哈哈哈!!!玩笑归玩笑,让我们开始学习吧!
首先我们还得从 PIL 库里导入一个模块:from PIL import ImageFilter
使用滤镜的方法:photo2 = photo1.filter(ImageFilter.CONTOUR)
,我解释一下,其中 photo1 是原图,我们调用 filter 方法,参数(ImageFilter.滤镜),其中此处的 CONTOUR 是系统自带的滤镜(此处称之为铅笔画滤镜),此过程会返回一个图片对象,我们将此对象传递给变量 photo2
编码开始,在 python 文件(part1.py)中改写代码块
part1.py
文件代码如下:
from PIL import Image
from PIL import ImageFilter
photo1 = Image.open("小蕾姆.jpg")
# 铅笔画滤镜
photo2 = photo1.filter(ImageFilter.CONTOUR)
photo2.save("images\\pencil drawing.jpg")
pencil drawing.jpg
(铅笔图效果、图片大小:443.85kB)文件如下:
你觉得我只是讲一个滤镜嘛???那你就错了,让我们再次改写 python 文件(part1.py)中的代码块,将 ImageFilter.CONTOUR
(铅笔画效果) 改写成 ImageFilter.EMBOSS
(浮雕效果)
浮雕效果图如下(图片大小:285.35kB)
你认为就这了吗???让我们再将 ImageFilter.EMBOSS
(浮雕效果)改写成 ImageFilter.BLUR
(模糊效果)
模糊效果图如下(图片大小:212.42kB)
就这就这???不不不,让我们再将 ImageFilter.BLUR
(模糊效果)改写成 ImageFilter.EDGE_ENHANCE
(锐化效果)
锐化效果图如下(图片大小:475.79kB)
有了锐化,也应该有有柔和效果吧?!于是让我们再将 ImageFilter.EDGE_ENHANCE
(锐化效果)改写成 ImageFilter.SMOOTH
(柔和效果)
柔和效果图如下(图片大小:257.12kB)
重点:我们可以自定义滤镜效果(让我们来细致的耍耍)
我们针对于 ImageFilter.SMOOTH
(柔和效果)这行代码,鼠标拖到到下图红方框区,按住键盘上面的 ctrl 键加上鼠标左键点击进入
此时我们可以发现, ImageFilter.SMOOTH
(柔和效果)这行代码是引用了另一个模块(ImageFilter)中的一个滤镜类(SMOOTH)
我们来重写 SMOOTH 类,将此类复制一份到 part1.py 文件里并作出如下修改
因为类的位置发生了变化,引用时,由模块外引用转换成了模块内引用,所以定义的类也要发生相应的变化,类的名字我们定义成 MY_FILTER(我的滤镜)
part1.py
文件代码如下:
from PIL import Image
from PIL import ImageFilter
class MY_FILTER(ImageFilter.BuiltinFilter):
name = "my_filter"
# fmt: off
filterargs = (3, 3), 13, 0, (
1, 1, 1,
1, 1, 1,
1, 1, 1,
)
# fmt: on
photo1 = Image.open("小蕾姆.jpg")
photo2 = photo1.filter(MY_FILTER)
photo2.save("images\\Soft graph1.jpg")
我们将 MY_FILTER 类中参数 filterargs 的 3 x 3 方格中间的 5 改成 3
柔和效果图如下(自定义滤镜、图片大小:209.47kB)
我们发现与之前的柔和效果相比,亮度降低了
好啦好啦!!!滤镜我就介绍到这里了,如果大家还想继续玩玩,可以去继续尝试修改参数,至于到底要不要深究这个自定义滤镜,就看你们自己了!!!加油
图片剪切
哈哈哈!!!图片剪切,大家不要乱切哦,要按规矩办事,别把人家截了半个身子过来,废话少说,继续学习
此处我们只需要导入 PIL 库中的 Image 模块, from PIL import Image
图片剪切:photo2 = photo1.crop((1100, 0, 2000, 600))
,crop 方法需要一个元组(x1,y1,x2,y2)作为参数,具体介绍如下:
我们修改 part1.py 文件,使其剪切一张图片
part1.py
文件如下:
from PIL import Image
photo1 = Image.open("小蕾姆.jpg")
photo2 = photo1.crop((1100, 0, 2000, 600))
photo2.save("images\\半个小蕾姆.jpg")
半个小蕾姆.jpg
文件如下:
总有手不跟着想法走的时候啦!!!大家要原谅我才对!!!我不是故意截半个身子下来的!!!
图片粘贴
粘来粘去真好玩儿,用此方法来进行小图贴在大图上或者来做几张图的对比图,肯定是一件非常有趣的事情,学习吧!
此处我们只需要导入 PIL 库中的 Image 模块, from PIL import Image
我们修改 part1.py 文件,使其完成粘贴功能1
part1.py
文件如下:
from PIL import Image
photo1 = Image.open("小蕾姆.jpg")
photo2 = Image.open("Doraemon.png")
photo1.paste(photo2, (0, 0))
photo1.save("images\\Doraemon_小蕾姆.png")
加载二张图片 小蕾姆.jpg
(photo1) 和 Doraemon.png
(photo2),photo1 为主图,我们将 photo2 粘贴到主图上面,针对代码块 photo1.paste(photo2, (0, 0))
,第一个参数是 副图,第二个参数是副图置于主图的位置(此坐标是副图左上角在主图上的相对坐标)
Doraemon_小蕾姆.png
文件如下:
图片粘贴当然不仅仅就这点东西,我们继续学习对比图的创建
我们修改 part1.py 文件,使其完成粘贴功能2
part1.py
文件如下:
from PIL import Image
photo1 = Image.open("小蕾姆.jpg")
photo2 = Image.open("pencil drawing.jpg")
Blankdiagram = Image.new("RGB", (4140, 1206), (255, 0, 0))
Blankdiagram.paste(photo1, (0, 0))
Blankdiagram.paste(photo2, (2073, 0))
Blankdiagram.save("images\\area chart.png")
加载二张图片 小蕾姆.jpg
(photo1)和 pencil drawing.jpg
(photo2),创建一张空白图片(Blankdiagram),针对代码块 Blankdiagram = Image.new("RGB", (4140, 1206), (255, 0, 0))
,RGB 是颜色显示模式, (4140, 1206) 是空白图的大小,(255, 0, 0) 是空白图的背景色
area chart.png
文件如下:
是不是觉得挺好玩的哦!!!针对之前用不同滤镜配置后的图,你有没有新的想法呢?
图片缩放
此处我们只需要导入 PIL 库中的 Image 模块, from PIL import Image
我们修改 part1.py 文件,使其完成缩放功能
part1.py
文件如下:
from PIL import Image
photo1 = Image.open("小蕾姆.jpg")
photo2 = Image.open("Doraemon.png")
photo2.thumbnail((50, 50))
photo1.paste(photo2, (0, 0))
photo1.save("images\\small_Doraemon_小蕾姆.png")
为了我们对比的方便,我们使用了之前的代码,针对代码块 photo2.thumbnail((50, 50))
,我们将 Doraemon.png
从 350 x 350 缩小到了 50 x 50
small_Doraemon_小蕾姆.png
文件如下:
特别注意:缩放是按照比例严格执行的(即使我们本身输入的数据不足以按比例进行缩放,电脑也会自动以最完美的方法来缩放)
好像又有一个好玩的东西?镜像?啊!有点懵!
镜像效果
赶快学起来,学起来!!!
此处我们只需要导入 PIL 库中的 Image 模块, from PIL import Image
我们修改 part1.py 文件,使其完成镜像效果
part1.py
文件如下:
from PIL import Image
photo1 = Image.open("小蕾姆.jpg")
photo2 = photo1.transpose(Image.FLIP_LEFT_RIGHT)
photo3 = photo1.transpose(Image.FLIP_TOP_BOTTOM)
photo2.save("images\\Left and right mirror image.png")
photo3.save("images\\up and down mirror image.png")
此处针对 photo2 = photo1.transpose(Image.FLIP_LEFT_RIGHT)
,参数为 Image.FLIP_LEFT_RIGHT
时是左右镜像,参数为 Image.FLIP_TOP_BOTTOM
时是上下镜像,调用此方法返回一个新的图片
Left and right mirror image.png
文件如下:
up and down mirror image.png
文件如下:
文字水印
谈起水印,博主可是感到很大的忧伤,好不容易发现了一张找了好久的图,可是上面却积累了大量的水印痕迹!!!害!我也学习水印去了,哼!
此处我们还需要导入 PIL 库中的 ImageFont 和 ImageDraw 模块, from PIL import ImageFont, ImageDraw
我们修改 part1.py 文件,使其完成水印效果
part1.py
文件如下:
from PIL import Image, ImageFont, ImageDraw
photo1 = Image.open("小蕾姆.jpg")
# 1. 创建字体对象
font = ImageFont.truetype("msyh.ttc", 100)
# 2. 创建 draw 对象
draw = ImageDraw.Draw(photo1)
# 3. 文字渲染
draw.text((0, 0), "小涵", font=font, fill=(255, 0, 0))
photo1.save("images\\xiaohan_小蕾姆.png")
此处针对代码 font = ImageFont.truetype("msyh.ttc", 100)
,第一个参数是字体路径,第二个参数是字体大小,针对代码 draw = ImageDraw.Draw(photo1)
,可以理解为在图片 photo1 上画水印,针对代码 draw.text((0, 0), "小涵", font=font, fill=(255, 0, 0))
,第一个参数是水印位置,第二个参数是水印内容,第三个参数是内容字体,第四个参数是字体颜色
xiaohan_小蕾姆.png
文件如下:
重点:字体路径的设置
- 我们得先找到系统 C 盘内的 fonts 文件夹
- 不知道又会不会被违规哈,此处不展示字体文件
- 然后我们复制其中一项字体文件(MiNiJianPangWa-1),粘贴到 PIL 文件夹下
我们稍微修改一下 part1 的代码
part1.py
代码如下:
from PIL import Image, ImageDraw, ImageFont
photo1 = Image.open("小蕾姆.jpg")
draw = ImageDraw.Draw(photo1)
font = ImageFont.truetype("MiNiJianPangWa-1.ttf", 200)
draw.text((0, 0), "小涵", font=font, fill=(255, 0, 0))
photo1.save("images\\xiaohan.png")
xiaohan.png
文件如下:
颜色块
什么是颜色块???它是一种用颜色来填充像素块的方式,乍一看,感觉好高级的样子!!!学起来学起来!
此处我们还需要导入 PIL 库中的 ImageDraw 模块, from PIL import ImageDraw
我们修改 part1.py 文件,使其完成颜色块效果
part1.py
文件如下:
from PIL import Image, ImageDraw
import random
Blankdiagram = Image.new("RGB", (1500, 900), (255, 255, 255))
# 创建一张空白图、颜色模式为 RGB、大小为 (600, 600)、颜色为白色
# 1. 创建 draw 对象
draw = ImageDraw.Draw(Blankdiagram)
# 2. 渲染颜色
for x in range(200, 600):
for y in range(200, 600):
color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
draw.point((x, y), color)
Blankdiagram.save("images\\Rendered graph.png")
针对代码 draw.point((x, y), color)
,第一个参数是像素点,第二个参数是渲染颜色
Rendered graph.png
文件如下:
这个生成的图是不是很像一个验证码啊?!我觉得好像,应该,也是有点像的
验证码
冲冲冲!!!
此处我们还需要导入 PIL 库中的 ImageFont 和 ImageDraw 模块, from PIL import ImageFont, ImageDraw
我们修改 part1.py 文件,使其完成验证码效果
Rendered graph.png
文件如下:
part1.py
文件如下:
from PIL import Image, ImageDraw, ImageFont
import random
photo1 = Image.open("images\\Rendered graph.png")
# 1. 创建 draw 对象
draw = ImageDraw.Draw(photo1)
# 3. 渲染数字
for x in range(0, 4):
font = ImageFont.truetype("msyh.ttc", random.randint(200, 300))
num = str(random.randint(0, 9))
y = random.randint(300, 600)
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
draw.text((x * 400, y), num, fill=(r, g, b), font=font)
photo1.save("images\\security code.png")
security code.png
文件如下:
补充
我们来尝试在一张图上创建文字水印
下列程序是在一张创建的空白图(与原图大小完全一致)上面创建文字
from PIL import Image, ImageDraw, ImageFont
import random
# 字体路径
FONT_PATH = 'MiNiJianPangWa-1.ttf'
# 字体大小
FONT_SIZE = 8
# 间隔大小
SPACE_SIZE = 15
def draw(draw_text):
# 以指定的模式和大小创建一个新图像(白色填充且与需操作图大小完全相同)
Blankdiagram = Image.new("RGB", (350, 350), color="white")
# 创建 draw 对象
draw1 = ImageDraw.Draw(Blankdiagram)
# 创建字体对象 自定义字体样式及大小
font = ImageFont.truetype(FONT_PATH, size=FONT_SIZE)
# 通过两个 for 循环,依次定位到每个文字所在的色块
for i in range(0, 350, SPACE_SIZE):
# SPACE_SIZE 为步长
for j in range(0, 350, SPACE_SIZE):
# SPACE_SIZE 为步长
draw1.text((j, i),
draw_text[int(j / SPACE_SIZE) % len(draw_text)],
fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)),
font=font)
Blankdiagram.save("images\\哆啦哆啦.jpg")
draw("哆啦A梦")
# 可以自己更改文字哦
哆啦哆啦.jpg
文件如下:
在各大抠图软件,将白色背景面扣去,得到一张透明的图
哆啦哆啦抠图后.png
文件如下(保存为 png 格式)
from PIL import Image, ImageDraw, ImageFont
photo1 = Image.open("images/哆啦哆啦抠图后.png").convert("RGBA")
photo2 = Image.open("Doraemon.png").convert("RGBA")
final = Image.new("RGBA", (350, 350))
final = Image.alpha_composite(final, photo2)
final = Image.alpha_composite(final, photo1)
final.convert("RGB")
final.save("images\\哆啦哆啦_Doraemon.png")
此处针对代码 photo1 = Image.open("images/哆啦哆啦抠图后.png").convert("RGBA")
,添加这一行代码 .convert(RGBA) 是因为调用 Image 模块的 alpha_composite 方法时二个参数(图片)的模式必须指定为 RGBA,针对代码 final.convert("RGB")
,保存文件的时候又必须把图片颜色模式转换为 RGB
哆啦哆啦_Doraemon.png
文件如下: