Skip to main content

修改图片大小

最近服务器需要接口更新了,一些不合规的数据需要批量处理一下

# -*- coding: utf-8 -*-
#
# @Author: CPS
# @email: 373704015@qq.com
# @Date:
# @Last Modified by: CPS
# @Last Modified time: 2021-08-30 10:23:04.562765
# @file_path "Z:\CPS\MyProject\test"
# @Filename "s.py"
# @Description: 功能描述
#

import pathlib
from PIL import Image,ImageFile

# 忽略 TRUNCATED 错误
ImageFile.LOAD_TRUNCATED_IMAGES = True

def resize(p:str, ext:str, limt:int=300, mode:str="RGB"):
"""
Description 过滤太大的图片,批量缩小为小图

- param p :{str} 要遍历的目录
- param ext :{str} 要处理的格式 *.jpg/*.png 等
- param mode :{str} 如果带透明,应该使用 RGBA模式

returns `{}` {description}

"""
p = pathlib.Path(p)
count = 0
for each in p.glob(ext):
# 不合法的文件删除/或者跳过

if int(each.stat().st_size) == 0: continue
# each.unlink()

img = Image.open(each.resolve())

img_w,img_h = img.size
new_w = new_h = 0

isLimt_w = img_w > limt and img_w > img_h
isLimt_h = img_h > limt and img_w < img_h

if isLimt_w:
new_w = limt
new_h = img_h * new_w / img_w

elif isLimt_h:
new_h = limt
new_w = img_w * new_h / img_h

if isLimt_w or isLimt_h:
try:
img.convert(mode).resize((int(new_w),int(new_h))).save(each.resolve())
count +=1
except Exception as e:
print(f'{each}文件出错,', e)
finally:
pass

print(f'成功处理 {count} 个 [{ext}] 文件 ')

if ( __name__ == "__main__"):
tar = r'Z:\CPS\MyProject\test\tmp'
# tar = r'/home/hongqi/server/app/public/upload/tmp'
resize(tar,'*.jpg')
resize(tar,'*.png', mode='RGBA')

错误/损坏图片处理

OSError: image file is truncated (xxxxx bytes not processed)

OSError: image file is truncated (0 bytes not processed)

  • PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True 损坏图片是否抛出错误

这里的 PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True 是让PIL对一些损坏的jpg图片跳过,不进行处理,因为是用户上传的图片,一些上传到一般,或者网络原因没传完的不完全图像文件,这些都被识别为损坏文件,要么删除,要么跳过

​ 其实PIL.ImageFile.LOAD_TRUNCATED_IMAGES = True的原理是识别图片的结尾,是否跟约定的图片格式规则(详细参考EOI规范)相同,比如jpg图片必须是 FF D9的结尾,这