【问题标题】:How to loop through one element of a zip() function twice - Python如何循环遍历 zip() 函数的一个元素两次 - Python
【发布时间】:2013-06-22 17:32:00
【问题描述】:

所以这是我的困境...我正在编写一个脚本,它从文件夹中读取所有 .png 文件,然后将它们转换为我在列表中指定的多个不同维度。一切正常,除了在处理一张图像后退出。

这是我的代码:

sizeFormats = ["1024x1024", "114x114", "40x40", "58x58", "60x60", "640x1136", "640x960"]

def resizeImages():

widthList = []
heightList = []
resizedHeight = 0
resizedWidth = 0

#targetPath is the path to the folder that contains the images
folderToResizeContents = os.listdir(targetPath)

#This splits the dimensions into 2 separate lists for height and width (ex: 640x960 adds
#640 to widthList and 960 to heightList
for index in sizeFormats:
    widthList.append(index.split("x")[0])
    heightList.append(index.split("x")[1])

#for every image in the folder, apply the dimensions from the populated lists and save
for image,w,h in zip(folderToResizeContents,widthList,heightList):
    resizedWidth = int(w)
    resizedHeight = int(h)
    sourceFilePath = os.path.join(targetPath,image)
    imageFileToConvert = Image.open(sourceFilePath)
    outputFile = imageFileToConvert.resize((resizedWidth,resizedHeight), Image.ANTIALIAS)
    outputFile.save(sourceFilePath)

如果目标文件夹包含名为 image1.png,image2.png 的 2 个图像,将返回以下内容(为了可视化,我将在下划线后添加应用于图像的尺寸):

image1_1024x1024.png, ....., image1_640x690.png(返回 image1 的所有 7 个不同尺寸)

当我需要它对 image_2 应用相同的转换时,它会停在那里。我知道这是因为 widthList 和 heightList 的长度只有 7 个元素长,因此在 image2 轮到它之前退出循环。有什么方法可以为targetPath中的每个图像循环遍历widthList和heightList?

【问题讨论】:

    标签: python image loops resize zip


    【解决方案1】:

    嵌套你的 for 循环,你可以将所有 7 个维度应用于每个图像

    for image in folderToResizeContents:
        for w,h in zip(widthList,heightList):
    

    第一个 for 循环将确保它发生在每个图像上,而第二个 for 循环将确保图像被调整到每个大小

    【讨论】:

    • 我试过嵌套它,但是当你这样做时,每张图片都会采用列表的最后一个维度 (640x960)
    • @ColeGoodyear 不应该,这意味着你设置错了
    【解决方案2】:

    为什么不保持简单:

    for image in folderToResizeContents:
        for fmt in sizeFormats:
            (w,h) = fmt.split('x')
    

    注意您正在覆盖生成的文件,因为您没有更改输出路径的名称。

    【讨论】:

    • 这有助于分离宽度和高度,但它无助于解决我遇到的真正问题,即将这些属性附加到目标文件夹中的每个图像
    • 啊,我确实在覆盖文件!添加了一些花絮以生成唯一的名称,它按预期工作。非常感谢您的意见,我很感激
    【解决方案3】:

    您需要重新遍历每个文件的 sizeFormats。除非您对高度和宽度的循环迭代器变得更加棘手,否则 Zip 不会这样做。

    有时,当几个嵌套的 for 循环正常工作时,诸如 zip 之类的工具会生成更长更复杂的代码。我认为这比拆分为多个列表然后将它们重新组合在一起更直接。

    sizeFormats = ["1024x1024", "114x114", "40x40", "58x58", "60x60", "640x1136", "640x960"]
    sizeTuples = [(int(w), int(h)) for w,h in map(lambda wh: wh.split('x'), sizeFormats)]
    
    def resizeImages():
    
        #for every image in the folder, apply the dimensions from the populated lists and save
        for image in os.listdir(targetPath):
            for resizedWidth, resizedHeight in sizeTuples:
                sourceFilePath = os.path.join(targetPath,image)
                imageFileToConvert = Image.open(sourceFilePath)
                outputFile = imageFileToConvert.resize((resizedWidth,resizedHeight), Image.ANTIALIAS)
                outputFile.save(sourceFilePath)
    

    【讨论】:

    • 当我运行它时,我遇到了与尝试下面的 Stephan 代码时相同的问题。每个图像都采用列表的最后一个维度,因此每个输入 .png 最终都有 7 个图像,它们都是 640x960
    • 我专注于迭代部分......另见@Steve Barnes 回答。 outputFile.save(sourceFilePath) 不断覆盖您的文件(实际上,您覆盖了原始输入文件)。您需要生成唯一名称,可能通过将 sizeFormats 字符串附加到文件。
    • 啊,你是圣人,我不敢相信我忽略了这一点!添加了一些花絮以生成唯一的名称,它按预期工作。谢谢你的帮助
    猜你喜欢
    • 2021-10-26
    • 2015-11-10
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 2018-05-17
    • 1970-01-01
    相关资源
    最近更新 更多