Цель:
Я пытаюсь пакетно обработать изображения, содержащиеся в папке, чтобы изменить их размер и оптимизировать их для использования в Интернете.
Проблема:
Следующий скрипт работает, но мне нужно запустить его дважды , прежде чем я получу нужный вывод.Вот как я ожидаю, что это сработает:
функция 1: resize_aspect_fit ()
Изменяет размеры каждого изображения в целевой папке до определенного размера, добавляет "_small.png" к имени файлаи сохраняет его как новый файл в подпапке «optimized_images», созданный в том же каталоге, что и исходная группа изображений.
function2: png_conversion ()
Принимает вновь созданные изображения внутри«optimized_images» («_small.png») и применяет преобразование, которое уменьшает размер исходного файла, добавляя суффикс «-opt.png», чтобы указать, что он был оптимизирован.
function3: unoptimized_cleanup ()
Принимает файлы, созданные функцией 1, которые больше не нужны (поскольку они были оптимизированы), и удаляет их, чтобы уменьшить беспорядок.
При запуске сценария я получаю ожидаемый ответиз функции 1 все файлы в целевом файле изменяются соответствующим образом и сохраняются в папке «optimized_images».Но мне нужно запустить сценарий второй раз, чтобы функции 2 и 3 вступили в силу.Это работает, но я никогда не сталкивался с такой проблемой раньше.Любая идея, почему это происходит?
Что я пробовал:
Я думал, что это может быть связано с операциями открытия / закрытия файлов, но я думаю, что закрываю их все в соответствующее время.Я поменял местами синтаксис Image.open, чтобы использовать «с Image.open (путь) как изображение:», но это не решило проблему.
Я подумал, что могут быть некоторые проблемы с os.listdir или os.path, гдевозможно, придется выполнить «сброс», чтобы дважды просмотреть каталог файлов, но я ничего не могу найти.
from PIL import Image
import os, sys
path = "../path/to/images/"
new_folder = '/optimized_images/'
optimized_path = path + new_folder[1:]
dirs = os.listdir( path )
optimized_dirs = os.listdir( optimized_path )
def resize_aspect_fit(final_size=250, dirs=dirs, optimized_path=optimized_path, optimized_dirs=optimized_dirs):
for item in dirs:
if item == '.DS_Store':
continue
if os.path.isfile(path+item):
with Image.open(path+item) as im:
f, e = os.path.splitext(path+item)
size = im.size
ratio = float(final_size) / max(size)
new_image_size = tuple([int(x*ratio) for x in size])
im = im.resize(new_image_size, Image.ANTIALIAS)
new_im = Image.new("RGBA", (final_size, final_size), color=(255,255,255,0))
new_im.paste(im, ((final_size-new_image_size[0])//2, (final_size-new_image_size[1])//2))
new_path, new_filename = f.rsplit('/', 1)
new_im.save(new_path + new_folder + new_filename + '_small.png', 'PNG', quality=10, optimize=True)
new_im.close()
def png_conversion(optimized_dirs=optimized_dirs, optimized_path=optimized_path):
for item in optimized_dirs:
if item == '.DS_Store':
continue
f, e = os.path.splitext(optimized_path+item)
with Image.open(f + e) as im:
im.load()
# Get the alpha band
alpha = im.split()[-1]
im = im.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255)
# Set all pixel values below 128 to 255,
# and the rest to 0
mask = Image.eval(alpha, lambda a: 255 if a <=128 else 0)
# Paste the color of index 255 and use alpha as a mask
im.paste(255, mask)
# The transparency index is 255
e = e.split('.png')[0]
im.save(f + e + "-opt.png", transparency=255)
im.close()
def unoptimized_cleanup(optimized_dirs=optimized_dirs, optimized_path=optimized_path):
for item in optimized_dirs:
if item.endswith('small.png'):
os.remove(os.path.join(optimized_path, item))
#functions called in order
resize_aspect_fit(final_size=250, dirs=dirs)
png_conversion(optimized_dirs=optimized_dirs, optimized_path=optimized_path)
unoptimized_cleanup(optimized_dirs=optimized_dirs, optimized_path=optimized_path)
Я ожидаю, что для следующей структуры папок:
folder/image1.png
folder/image2.png
вывод должен выглядеть следующим образом, с файлами соответствующего размера и меньшего размера:
folder/optimized_images/image1_small-opt.png
folder/optimized_images/image2_small-opt.png
Соответствующие источники, которые я извлек из:
Преобразование PNG32 в PNG8 с PIL при сохранении прозрачности
Python / PIL Изменение размера всех изображений в папке
Извините за длинный вопрос / код, и заранее спасибо за любую помощь !!