简体   繁体   中英

PIL Images saving in wrong order (for loop, enumerate indexes)

I'm coding a program that, for all the files in a directory (the 101 files are already named 0.jpg to 100.jpg, in order) opens the files, resizes them based on a ratio, then saves the output in a different directory according to the index of the for loop with enumerate. I'm confused as to why my indexes and filenames aren't matching up. The index of the for loop runs from 0 to 100 and so do the file names. The for loop should call the source image files in sequential order from 0 to 100 and save them in sequential order because of the index.

But, when I run the program, what was source image 100 (which should be the largest resized image) is now saved as 3.jpg and is the fourth smallest image. What was image 3 is now image 24. Maybe more changes result from that. However, at larger images, the order is correct.

Here is my code:

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

I even made sure to sort files. The ratios and indexes all print correctly. What's happening here?

os.listdir may not return an properly sorted arary. You should sort the array before you iterate over it. A better way to do this is to use the original file name instead of the iterator.
You can try the following code that uses an array.sort() function.

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()

Update on 26/9/2017
I have tested your code in my computer. I have found I made a mistake in sort() .
Here is the console printing the parameter throughout the iteration.

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

The problem of sort() function will is that the function always compares the string character by character. Therefore, the result will not match the index.
I have made a little changes on your code. It works in my computer to produce an expected result.

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')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM