前言
最近在博客中做了一个相册功能,但是问题是我的图片都很大,用图片压缩工具压缩了一遍感觉不是很方便,于是就搜了一下python相关工具,后来发现知乎上的一篇文章《如何用Python智能批量压缩图片》,这里感谢作者提供了思路,短短几行代码实现了图片压缩需求。
最后添加了图片水印功能,可以方便配置图片路径来实现压缩和水印添加,本来打算使用 Tkinter 来实现一个图片界面方便操作,后来想想还是把精力放在核心逻辑上面吧,其实使用图形界面不见的就很方便,这样修改配置其实更方便些,如果你想实现成图形界面可参考我的另一篇博文《Python两个案例练习》。
知识点
内置模块和第三方模块
在 python 中,一个 .py 文件就可以理解为一个模块,模块之间可以互相引用。
模块分为三种:自己写的、内置的、第三方的。
内置模块一般存放在安装目录的lib
目录下,第三方库一般存放在安装目录的lib\site-packages
目录下。第三方库使用前需要提前安装,例如 Python 操作图像的模块 PIL 需要提前安装。
两种导入方式,例如下面导入module1
并调用模块方法 say()
:
#第一种导入方式
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)。
#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)
添加水印
#预定义一个字体
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)
完整代码
#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
这个插件目前几乎支持所有语言的编译和运行,非常好用方便,安装好后操作栏会多出一个运行的小三角按钮,点击运行即可。
作者:水寒
出处:https://dp2px.com/2019/03/26/python-compress/#more
51reboot 在8.23日(周五)《基于云服务的 DevOps工作流》 分享
时间:8.23日21:00-22:00
分享内容如下:
1、 背景
2 、工作流引擎
3、 用例
4 、演示
分享人:
架构师莱米,目前就职于某外企云服务商。
10多年的软件开发和团队管理经验,丰富的互联网应用和企业应用架构项目经历。
戳这儿