PIL 图像以错误的顺序保存(for 循环,枚举索引)

Posted

技术标签:

【中文标题】PIL 图像以错误的顺序保存(for 循环,枚举索引)【英文标题】:PIL Images saving in wrong order (for loop, enumerate indexes) 【发布时间】:2017-09-25 00:42:45 【问题描述】:

我正在编写一个程序,对于目录中的所有文件(101 个文件已经按顺序命名为 0.jpg 到 100.jpg)打开文件,根据比例调整它们的大小,然后保存根据带有枚举的for循环的索引在不同的目录中输出。我对为什么我的索引和文件名不匹配感到困惑。 for 循环的索引从 0 到 100,文件名也是如此。 for 循环应该按从 0 到 100 的顺序调用源图像文件,并因为索引而按顺序保存它们。

但是,当我运行程序时,源图像 100(应该是最大的调整大小的图像)现在保存为 3.jpg 并且是第四小的图像。以前的图像 3 现在是图像 24。也许更多的变化会由此产生。但是,在较大的图像中,顺序是正确的。

这是我的代码:

os.makedirs("resized images")
try:
    files = os.listdir(os.path.join(os.getcwd(),"source images"))
except IOError:
    print('No folder found.')
    input('Enter any key to exit: ')
    exit()

xDimension=dimensions[0]
yDimension=dimensions[1]
print(xDimension)
print(yDimension)
totalViews=0
for item in d:
    totalViews+=d[item]
files.sort()
for index, file in enumerate(files):
    path = os.path.join(os.getcwd(), "source images", file)
    img = Image.open(path)
    ratio=(d[index]/totalViews)
    print(ratio)
    print(str(index))
    resizedX=int(math.ceil((xDimension*ratio)))
    resizedY=int(math.ceil((yDimension*ratio)))
    resized=img.resize((resizedX, resizedY))
    resized.save("resized images/"+str(index)+".jpg", 'JPEG')
#image 100 in source images becomes image 3 in resized images, making image 3 become image 24

我什至确保对文件进行排序。比率和索引都正确打印。这里发生了什么?

【问题讨论】:

如果在 files.sort() 之前 print(files) 会得到什么?如果你在它之后打印(文件)呢? 【参考方案1】:

os.listdir 可能无法返回正确排序的数组。您应该在迭代之前对数组进行排序。更好的方法是使用原始文件名而不是迭代器。 您可以尝试以下使用array.sort() 函数的代码。

try:
    files = os.listdir(os.path.join(os.getcwd(),"source images"))
    files.sort()
except IOError:
    print('No folder found.')
    input('Enter any key to exit: ')
    exit()

2017 年 9 月 26 日更新 我已经在我的电脑上测试了你的代码。我发现我在sort() 中犯了一个错误。 这是在整个迭代过程中打印参数的控制台。

file = 0.png
index = 0

file = 1.png
index = 1

file = 10.png
index = 2

file = 11.png
index = 3

file = 12.png
index = 4

file = 13.png
index = 5

file = 14.png
index = 6

file = 2.png
index = 7

file = 3.png
index = 8

sort()函数的问题是函数总是逐字符比较字符串。因此,结果将与索引不匹配。 我对你的代码做了一些改动。它在我的电脑上工作以产生预期的结果。

for index, file in enumerate(files):
    path = os.path.join(os.getcwd(), "source images", file)
    img = Image.open(path)
    # do your operation 
    # Use the file name itself instead of the index
    img.save("resized images/"+ file, 'JPEG')

【讨论】:

欢迎!请不要在答案中提问。尽量简洁明了,并在可能/必要时提供代码。 感谢您的提醒。我稍后会编辑它。打扰了。 我可能确实必须使用原始文件名,但我已经使用 files.sort() 对代码中的文件进行了排序,并且产生了相同的损坏结果。

以上是关于PIL 图像以错误的顺序保存(for 循环,枚举索引)的主要内容,如果未能解决你的问题,请参考以下文章

Python PIL将图像保存在目录中,如果名称相同,则不覆盖

通过套接字发送pil图像而不保存python

使 Completionhandler 在 For 循环中工作以获取图像

matplotlibPILcv2图像操作差异分析

如何以相反的顺序快速迭代for循环?

使用 PIL 保存图像