python批量压缩图像的完整步骤
作者:yuanzhoulvpi 发布时间:2022-05-14 16:10:47
背景
今天在工作中,同事遇到一个上传图片的问题:系统要求的图片大小不能超过512KB。但是同事又有很多照片。这要是每一个照片都用ps压缩的话,那岂不是很崩溃。于是我写了一个脚本,可以批量压缩图片到指定大小。直接造福同事、提高同事的工作效率。
解决方案
其实也不用卖关子了,就是使用python的pillow包就可以对图片进行压缩,如果一个图片已经压缩到指定大小了,那就停止压缩,如果没有达到指定大小,那就对压缩后的图片再进行压缩,直到压缩到自定范围内。
可是为什么不在网上找代码呢?我也是找过,但是发现很多代码质量参差不齐,都达不到我想要的效果,而且很不优雅。于是我随手就写了一个代码,不仅仅代码写的简单,而且逻辑清楚,最后为了效率,我还做了一个并行,同时使用10个进程处理。说实话,那可是真的飞快。
操作步骤
要求
默认是使用的是Anaconda的环境。
将所有要压缩的图片都放在一个文件夹下,然后每个图片的格式只能是下面三种:png,jpg, jpeg。如果是PNG也不行。因为PNG是png的大写。
代码中设置的图像的压缩后的大小是512KB,那么你可以设置代码中的target_size为500,只要比512KB小就行了。
然后把我的代码从GitHub上下载下来。代码链接为:https://github.com/yuanzhoulvpi2017/tiny_python/blob/main/image_compression/ic.py
步骤
我这里把所有图片都放在了一个文件夹里面,文件夹名称为历史截图。然后我的这个历史截图和ic.py代码都放在了little_code文件夹中。
在little_code文件夹下,打开终端。
直接运行的脚本:
python ic.py xxx_文件夹
等待一会,就会将整个文件夹下的所有图片都转化好了。
完整代码:
如果上不去GitHub的话,我直接把代码放在这里,保存为一个python文件即可。比如保存的文件名为:ic.py
from PIL import Image
from glob import glob
import os
from tqdm import tqdm
import shutil
import sys
from itertools import chain
from multiprocessing import Pool
# image_dir = "image_dir"
template_dir = 'template'
output_dir = 'output'
error_dir = 'error'
def clean_dir(dir_name):
if os.path.exists(dir_name):
shutil.rmtree(dir_name)
os.makedirs(dir_name)
else:
os.makedirs(dir_name)
# image_file_list = glob(f"{image_dir}/*")
# image_file_list
def imagesize(filepath):
"""
获得文件的磁盘大小
:param filepath:
:return:
"""
return os.path.getsize(filepath) / 1024
def compress_image(image_path):
raw_image = Image.open(image_path)
temp_image_name = image_path.split(os.sep)[-1]
template_image = os.path.join(template_dir, temp_image_name)
output_image = os.path.join(output_dir, temp_image_name)
error_image = os.path.join(error_dir, temp_image_name)
target_size = 500 # kb
try:
if imagesize(image_path) < target_size:
shutil.copyfile(image_path, output_image)
else:
width, height = raw_image.size
raw_image.resize((int(width * 0.9), int(height * 0.9)), Image.ANTIALIAS).save(template_image)
while imagesize(template_image) > target_size:
template_iamge2 = Image.open(template_image)
width_2, height_2 = template_iamge2.size
template_iamge2.resize((int(width_2 * 0.9), int(height_2 * 0.9)), Image.ANTIALIAS).save(template_image)
shutil.copyfile(template_image, output_image)
except Exception as e:
shutil.copyfile(image_path, error_image)
print(f'文件保存失败: {image_path}')
# print(e)
if __name__ == '__main__':
# 批量创建文件夹
[clean_dir(i) for i in [template_dir, output_dir, error_dir]]
image_dir = sys.argv[1]
image_file_list = list(chain(*[glob(os.path.join(image_dir, i)) for i in ['*.png', '*.jpg', '*.jpeg']]))
# for temp_image_path in tqdm(image_file_list):
# compress_image(temp_image_path)
print(f'\n\n文件保存父目录: {os.getcwd()}\n'
f'输出文件位置:{os.path.join(os.getcwd(), output_dir)}\n\n')
# parallel
P = Pool(processes=10)
pbar = tqdm(total=len(image_file_list))
res_temp = [P.apply_async(func=compress_image, args=(i,), callback=lambda _: pbar.update(1)) for i in
image_file_list]
_ = [res.get() for res in res_temp]
附:批量将图片的大小设置为指定大小
import os
from PIL import Image
# 源目录
project_dir = os.path.dirname(os.path.abspath(__file__))
input = os.path.join(project_dir, 'src')
# 输出目录
output = os.path.join(project_dir, 'dest')
def modify():
# 切换目录
os.chdir(input)
# 遍历目录下所有的文件
for image_name in os.listdir(os.getcwd()):
print(image_name)
im = Image.open(os.path.join(input, image_name))
im.thumbnail((128, 128))
im.save(os.path.join(output, image_name))
if __name__ == '__main__':
modify()
写在后面
这个代码说起来难,说起来也不难,如果认真看我历史的文章的话,上面代码中遇到的知识点都就会了。像是所谓的图像压缩、并行处理之类的,其实并不难。
来源:https://blog.csdn.net/yuanzhoulvpi/article/details/122049330
猜你喜欢
- 本文实例为大家分享了PyQt5单行文本框展示的具体代码,供大家参考,具体内容如下QLineEdit 是一个允许输入和编辑纯文本的单行控件。系
- 先 Create table 吧create table emp(id int not null primary key,name varc
- 在网上看了很多解决方法,都没有解决,后来我自己解决了这个问题:出现的问题:在cmd上 “pip install package” 时显示 s
- 本文实例介绍了asp对access数据库常见操作方法,查找记录,添加记录更新记录,删除记录等。一、查找记录find.htm<HTML&
- 1. 官方代码FUSE_MODULESTORCH.AO.QUANTIZATION.FUSE_MODULES的源代码2. fuse_modul
- 首先从 ueEditor官网 下载最新版本的包,目前官网上提供了ASP、.NET、PHP、JSP版本的,django版本只有一个第三方个人开
- 前言:Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数,itertools提供的几个“无限
- 1,ConfigParser模块简介假设有如下配置文件,需要在Pyhton程序中读取$ cat config.ini[db]db_port
- 以a=[1,2,3] 为例,似乎使用del, remove, pop一个元素2 之后 a都是为 [1,3],如下:>>>
- 首先Python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型。在程序设计中,鸭子类型(英语:duck typing)
- 对比Google Chrome、IE来说,在Windows环境下,Firefox 3.5的启动速度非常慢,据说是因为Firefox 3.5从
- 先看看这三段话:[1、企业文化对形成企业内部凝聚力和外部竞争力所起到的积极作用,越来越受到人们的重视。企业竞争,实质是企业文化的竞争。面临全
- 【简 介】熟悉网页设计的网友就知道,调用Style的方法很多,我们可以单击鼠标右键选择Custon Style来调用Style标准,也可以在
- 前言1 简介Kepler.gl作为一款强大的开源地理信息数据可视化工具,可以帮助我们轻松制作针对大规模矢量数据的可视化作品,从而辅助数据分析
- 从照片里面获取GPS信息。可交换图像文件常被简称为EXIF(Exchangeable
- Nextcloud 是一款自由 (开源) 的类 Dropbox 软件,由 ownCloud 分支演化形成。它使用 PHP 和 JavaScr
- python 判断三个数字中的最大值,具体代码如下所示:#判断三个数中最大值n1= int(input('please enter
- 本文实例为大家分享了Python实现井字棋小游戏的具体代码,供大家参考,具体内容如下import osdef print_board(boa
- 代码如下: 代码如下:///<summary> /// 将两个列不同的DataTable合并成一个新的DataTab
- Mootools 1.2手风琴(Accordion)教程原文地址:30 Days of Mootools 1.2 Tutoria