最近我校封楼,不能出去活动,正好有时间赶1588号信箱的进程。

因为这个项目最开始被定义为图片资源类网站项目,所以相册的搭建是必不可少的。为了方便照片的显示与查看,缩略图是必不可少的。

我们使用Python的Pillow(PIL)库进行图片处理。

Pillow库简介

安装

1
pip install Pillow

使用

在日常应用过程中,使用最多的是 Pillow 提供的 Image 模块,其提供了包括图像存储、变换以及一系列的相关处理功能。Pillow 使用 Image 对象来表示图像对象并基于其定义图像的属性信息以及可针对其进行的操作,后续即主要介绍通过 Image 对象可进行的图像操作。在 Python 中使用时,用户首先需从 PIL 中导入对应的 Image 模块。

1
from PIL import Image

基本操作

1
2
3
4
5
6
7
8
from PIL import Image

# 1.打开图片
img = Image.open("image1.jpg")
# 2.显示图片
img.show()
# 3.保存图片
img.save("image2.jpg")

图片变换

代码 含义
img.transpose(Image.FLIP_LEFT_RIGHT) 水平翻转
img.transpose(Image.FLIP_TOP_BOTTOM) 垂直翻转
img.rotate(n) 逆时针旋转n度
img.resize( ( width, height ) ) 图片缩放
img.crop( ( x1 , y1 , x2 , y2 ) ) 图片裁剪
  • 图片裁剪时的坐标是以左上角为原点,向右为x轴,向下为y轴的坐标系表示的。
    e.g. part = img.crop( ( 0 , 0 , 400 , 300 ) ) # 截取获得图像 img 左上角大小为 400 × 300 像素的矩形图像

图像类型转换

不同的图像数据具有不同的图像格式,进而拥有不同的组织数据的方式。对于 RGB 图像而言,图像拥有 R、G、B 三个通道,像素数据由三个对应三通道的 8 bit 数据组成;对于黑白图像而言,其每个像素由一个 8 bit 字节表示等等。在打开图像时,open 方法会自动解析图像的格式,用户可通过 Image 对象的 mode 属性获得图像的状态。

Image 对象可通过 convert 方法进行图像类型间的转换,其使用转换的目标类型的字符串为参数,返回转换后的 Image 对象,常见的类型包括 RGB(真彩)、L(黑白)、YCbCr(视频图像)、HSV(色调饱和度亮度彩色空间)。

我在尝试的过程中发现,PNG格式的图片保存为JPG会报错。经过查阅资料发现错误原因主要是因为PNG格式和JPG格式图片的通道数不同。

  • PNG是四通道:RGBA意思是红色,绿色,蓝色,Alpha的色彩空间,Alpha指透明度
  • JPG是三通道:RGB意思是红色,绿色,蓝色

所以,PNG格式图片要保存成JPG格式就要丢弃A通道:

1
2
3
4
5
from PIL import Image

img = Image.open("image1.png")
img = img.convert("RGB")
img.save("image/image2.jpg")

滤镜功能

1
img = img.filter(滤镜名称)

(这玩意我也没试过,但我估摸着它能解决的Ps都能解决,可能在批量处理脚本中有奇效)

图片处理脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

# 批量获取缩略图

import os
import sys
import datetime
from PIL import Image


if len(sys.argv) != 1:
path = sys.argv[1]
print("文件夹路径:" + sys.argv[1] + "\n")
else:
path = input("请输入文件夹路径:\n")
# 新建文件夹
if not os.path.exists(path + os.sep + "缩略图"):
os.mkdir(path + os.sep + "缩略图")
# 获取日期
now = datetime.datetime.now()
date = "_" + now.strftime("%Y-%m-%d")
if os.path.exists(path):
fileList = os.listdir(path)
n = 0
for _ in fileList:
oldname = path + os.sep + fileList[n]
if os.path.isfile(oldname):
img_path = Image.open(oldname)
img_path = img_path.convert("RGB")
# 缩放及裁剪图片
width, height = img_path.size
if width > height:
width = width*300//height
height = 300
else:
height = height*300//width
width = 300
img_size = img_path.resize((width, height))
if width > height:
crop = (width // 2 - 150, 0, width // 2 + 150, 300)
else:
crop = (0, height // 2 - 150, 300, height // 2 + 150)
img_crop = img_size.crop(crop)
# 处理图片后存储路径,以及存储格式
newname = path + os.sep + '缩略图' + os.sep + 's' + str(n + 1) + date + '.jpg'
img_crop.save(newname, 'JPEG')
print(oldname, '==>', newname)
n += 1
else:
print('路径不存在')

input("\n按Enter键退出...")

输入待处理的文件夹路径,最终会在该路径输出“缩略图”文件夹,里面是所有处理完的300*300缩略图(默认输出JPG)。缩放图片时按原图片的长宽比进行等比缩放,长宽中最小值为300,以方便裁剪。裁剪图片时默认居中裁剪,可能损失重要细节,可自行更改。

在缩略图名称中添加了日期以便按时间查找图片。

参考文章:
https://www.jb51.net/article/225452.htm
https://www.jb51.net/article/169875.htm