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

前言

最近在博客中做了一个相册功能,但是问题是我的图片都很大,用图片压缩工具压缩了一遍感觉不是很方便,于是就搜了一下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多年的软件开发和团队管理经验,丰富的互联网应用和企业应用架构项目经历。

戳这儿

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    小迈克阅读 2,862评论 1 3
  • 一个女人的荣与哀——杨贵妃 文/熊玲玲 杨贵妃,一个千古流传的名字;杨玉环,一个举世公认的美人。 自古英...
    樱花幽梦阅读 428评论 0 1
  • 我们俩回老家时,才临时决定,绕一圈才回去,这不,我们坐着动车,来到厦门。 一上车,我们就开启泡面模式,因为饿了,哈...
    妙熙怡阅读 202评论 0 0
  • 把握驱动人心的力量 春风化雨,润物无声 新人就是应该拼命学习,苦练技能。做最简单,最枯燥的工作锤炼技能熟练度。这个...
    复苏森林阅读 310评论 0 1
  • 今日正好是当前流行的、所称谓的“七夕情人节”。关于情人节有两个版本,一个是2月14日西方情人节,一个是我...
    南康必达阅读 165评论 0 0