gpt4 book ai didi

python - 为什么我必须运行这个 python 脚本两次才能正确格式化图像?

转载 作者:行者123 更新时间:2023-12-01 07:45:40 26 4
gpt4 key购买 nike

目标:

我正在尝试批量处理文件夹内包含的图像,以调整其大小并优化它们以供在线使用。

问题:

以下脚本有效,但我必须运行两次才能获得所需的输出。这就是我期望它的工作方式:

函数1:resize_aspect_fit()

将目标文件夹中的每个图像调整为特定大小,将“_small.png”添加到文件名中,并将其作为新文件保存在子文件夹“optimized_images”中,该子文件夹与原始图像组在同一目录中创建图片。

函数2:png_conversion()

将新制作的图像放入“optimized_images”(“_small.png”)中,并应用减小原始文件大小的转换,添加“-opt.png”后缀以表明它已经过优化。

函数3:unoptimized_cleanup()

获取不再需要的函数 1 构建的文件(因为它们已被优化)并删除它们,以减少困惑。

当我运行脚本时,我从 function1 得到了预期的响应,目标文件中的所有文件都被适当调整大小并保存在“optimized_images”文件夹中。但我必须在函数2和3生效之前再次运行该脚本。它确实有效,但我以前从未遇到过这样的问题。知道为什么会发生这种情况吗?

我尝试过的:

我认为这可能与文件打开/关闭操作有关,但我认为我会在适当的时间将它们全部关闭。我将 Image.open 语法替换为使用“with Image.open(path) as image:”,但这并没有解决问题。

我认为 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

我提取的相关来源:

Converting PNG32 to PNG8 with PIL while preserving transparency

Python/PIL Resize all images in a folder

很抱歉问题/代码很长,并提前感谢您的帮助!!

最佳答案

问题是您在运行步骤 1 之前创建了变量 optimized_dirs。因此,在执行步骤 1 之前,您在该目录中创建了一个文件列表,此时该目录为空。如果您第二次运行它,这些文件将位于 optimized_dirs 中,因此它可以工作。

解决方案是读取函数 png_compressionoptimized_dirs 的内容,即将 os.listdir(optimized_pa​​th ) 移动到其中。

顺便说一句:我发现您使用了一些魔法来构建路径,其中使用 [1:] 来防止双斜杠。使用 os.path.join 构建路径更加健壮,这将确保目录之间始终有一个斜杠,无论您是在每个目录的开头还是结尾指定它们。

关于python - 为什么我必须运行这个 python 脚本两次才能正确格式化图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56470781/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com