Python实现的图片压缩处理工具

前言

最近在博客中做了一个相册功能,但是问题是我的图片都很大,用图片压缩工具压缩了一遍感觉不是很方便,于是就搜了一下python相关工具,后来发现知乎上的一篇文章《如何用Python智能批量压缩图片》,这里感谢作者提供了思路,短短几行代码实现了图片压缩需求。

最后添加了图片水印功能,可以方便配置图片路径来实现压缩和水印添加,本来打算使用Tkinter来实现一个图片界面方便操作,后来想想还是把精力放在核心逻辑上面吧,其实使用图形界面不见的就很方便,这样修改配置其实更方便些,如果你想实现成图形界面可参考我的另一篇博文《Python两个案例练习》

知识点

内置模块和第三方模块

在python中,一个.py文件就可以理解为一个模块,模块之间可以互相引用。

模块分为三种:自己写的、内置的、第三方的。

内置模块一般存放在安装目录的lib目录下,第三方库一般存放在安装目录的lib\site-packages目录下。第三方库使用前需要提前安装,例如Python操作图像的模块PIL需要提前安装。

两种导入方式,例如下面导入module1并调用模块方法say():

1
2
3
4
5
6
#第一种导入方式
import module1
module1.say()
#第二种导入方式
from module1 import *
say()

from …import提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。

PIL模块

PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准库了。PIL功能非常强大,但API却非常简单易用。

安装:
在Debian/Ubuntu Linux下直接通过apt安装:$ sudo apt-get install python-imaging
Windows平台就去PIL官方网站下载exe安装包。

在本文中我安装的是Pillow,Pillow是一个对PIL友好的分支,作者是Alex Clark和贡献者。而PIL是一个Python图像处理库,作者是Fredrik Lundh和贡献者。

有关Pillow的中文文档请参考这里

glob模块

glob是python的内置模块,是一个文件操作相关模块,用它可以查找符合自己目的文件。

截止目前官方最新python版本是3.7.3,该版本的标准库文档链接——点这里查看

压缩实现

下面是用PIL实现的图片压缩函数,可直接粘贴修改目录使用(记得安装Pillow)。

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
#coding=utf-8
#!/usr/bin/python

from glob import glob
#pip install Pillow
from PIL import Image
import os
import math

SORUCE_DIR = 'D:\\blog\\gitlab\\source\\images\\photo'
TARGET_DIR= 'D:\\blog\\gitlab\\source\\images\\photo\\thumb'
THRESHOLD = 100000 #100kb
NEW_W_H = 800

def resize_images(source_dir, target_dir, threshold, new_w_or_h):
filenames = glob('{}/*'.format(source_dir))
if not os.path.exists(target_dir):
os.makedirs(target_dir)
for filename in filenames:
filesize = os.path.getsize(filename)
if filesize >= threshold:
print(filename)
with Image.open(filename) as im:
width, height = im.size
if width >= height:
new_width = new_w_or_h
new_height = int(new_width * height * 1.0 / width)
else:
new_height = new_w_or_h
new_width = int(new_height * width * 1.0 / height)
resized_im = im.resize((new_width, new_height))
output_filename = filename.replace(source_dir, target_dir)
resized_im.save(output_filename)


resize_images(SORUCE_DIR, TARGET_DIR, THRESHOLD, NEW_W_H)

添加水印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#预定义一个字体
FONT_FAMILY = 'C:\\Windows\\Fonts\\consola.ttf'

def add_text_to_image(image, text, font_size, font_family=FONT_FAMILY):
width, height = image.size
#相当于将图片转换为可以绘制的画布
img_draw = ImageDraw.Draw(image)
#创建字体画笔
Font = ImageFont.truetype(font_family, font_size)
#获取文字尺寸
textW,textH = Font.getsize(text)
#将文字写在屏幕右下角,文字白色透明度100/255
pointX = width - textW - textH / 2
pointY = height - textH - textH / 2
img_draw.text([pointX, pointY], text, fill=(255, 255, 255, 100), font = Font)

add_text_to_image(resized_im, "dp2px.com", 30)

完整代码

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#coding=utf-8
#!/usr/bin/python

from glob import glob
#pip install Pillow
from PIL import Image, ImageDraw, ImageFont
import os
import math

#原始图片目录
SORUCE_DIR = 'D:\\blog\\gitlab\\source\\images\\photo'
#处理后图片目录
TARGET_DIR= 'D:\\blog\\gitlab\\source\\images\\photo\\thumb'
#图片筛选条件
THRESHOLD = 100000 #100kb
#图片最大宽/高
NEW_W_H = 800
#是否开启水印 0不开启 1开启
WAHTER_MARK = 0

FONT_FAMILY = 'C:\\Windows\\Fonts\\constan.ttf'

def add_text_to_image(image, text, font_size, font_family=FONT_FAMILY):
width, height = image.size
#相当于将图片转换为可以绘制的画布
img_draw = ImageDraw.Draw(image)
#创建字体画笔
Font = ImageFont.truetype(font_family, font_size)
#获取文字尺寸
textW,textH = Font.getsize(text)
#将文字写在空白图像正中间
pointX = width - textW - textH / 2
pointY = height - textH - textH / 2
img_draw.text([pointX, pointY], text, fill=(255, 255, 255, 100), font = Font)


def resize_images(source_dir, target_dir, threshold, new_w_or_h):
#读取目录下所有文件
filenames = glob('{}/*'.format(source_dir))
#判断输出目录
if not os.path.exists(target_dir):
os.makedirs(target_dir)
#遍历处理
for filename in filenames:
filesize = os.path.getsize(filename)
#比较筛选
if filesize >= threshold:
with Image.open(filename) as im:
width, height = im.size
#判断图片方向(横/竖)
if width >= height:
new_width = new_w_or_h
new_height = int(new_width * height * 1.0 / width)
else:
new_height = new_w_or_h
new_width = int(new_height * width * 1.0 / height)
resized_im = im.resize((new_width, new_height))
#判断是否添加水印
if WAHTER_MARK != 0:
add_text_to_image(resized_im, "dp2px.com", int(new_w_or_h / 30))
#保存到输出目录
output_filename = filename.replace(source_dir, target_dir)
resized_im.save(output_filename)
print('图片处理完成!')

#调用处理方法处理图片
resize_images(SORUCE_DIR, TARGET_DIR, THRESHOLD, NEW_W_H)

啰嗦一句

最后给他家推荐一个编辑器来编辑和运行python程序,准确的说应该是一个插件。

编辑器:Visual Studio Code
插件:Code Runner

这个插件目前几乎支持所有语言的编译和运行,非常好用方便,安装好后操作栏会多出一个运行的小三角按钮,点击运行即可。