I am trying to learn the PIL’s image library and I am stuck yet a second time. What I am trying to do is read through a directory and all its subdirectories and only load, rotate and replace the images in a specific path entered by the user (or specified in the script). The problem is that line () in the code where I try to iterate through a function returned 2-tuple containing a list containing Imageobjects and another list containing strings raises the error:
“ValueError: too many values to unpack (expected 2)”.
I have tried doing a similar function in a separate script that returns the same type of 2-tuple that the get_subdirectory_images() function returns only without using any modules.
The real file with the error:
try:
    from PIL import Image
    from PIL import ImageEnhance
except ImportError:
    print("Please install Pillow using pip" + "nn")
import os
inp = "C:\Users\Isak Blomster\AppData\Roaming\.minecraft\resourcepacks\The python script pack\assets\minecraft\textures\items"
os.path.relpath(str(inp))
def get_subdirectory_images(target_directory_list, file_extension):
    images = []
    image_paths = []
    for current_directory, subdirectory_names, file_names in os.walk("."):
        tupl = (current_directory, subdirectory_names, file_names)
        #print(tupl)
        for target_directory in target_directory_list:
            if os.path.realpath(target_directory) == os.path.realpath(current_directory):
                #print("test")
                for name in file_names:
                    if name.endswith(file_extension):
                        image_path = os.path.join(current_directory, name)
                        image = Image.open(image_path)
                        images.append(image)
                        image_paths.append(image_path)
    return images, image_paths;
#print((get_subdirectory_images([str(inp)], ".png")))
for images, paths in get_subdirectory_images([str(inp)], ".png"):
    print("Test")
    rotated = images.rotate(90)
    rotated.save(paths)
Which returns this when run:
ValueError: too many values to unpack (expected 2)
This is a small scale which I seemingly got to work as I wanted?
class Image:
    """docstring for Image"""
    x = 0
    def __init__(self, x):
        self.x = x
    def give_xy(self, y):
        xy = self.x * y
        return xy
i = 0
def function(num1, num2):
    A = Image(num1)
    B = Image(num2)
    string_list = ["wow", "wow2"]
    object_list = [A, B]
    return string_list, object_list
for a, b in function(1, 2):
    i += 1
    if i > 1:
        print(a.give_xy(3), b.give_xy(4))
And it returns
3 8
The expected result is that all the images in the items subfolder should be rotated 90 degrees.
Advertisement
Answer
return images, image_paths
your function returns one tuple containing two lists of the same size.
Now the for loop iterates on the result, and first yields images which is a list of images (more than 2 images) that cannot fit in 2 variables. That explains the error message.
You could have built a dictionary or a list of tuples instead but if you want to iterate/associate images & paths you have to iterate on the zipped result
for images, paths in zip(*get_subdirectory_images([str(inp)], ".png")):
(variable names should be image, path, would be more logical)
As I mentionned above, returning a tuple of 2 lists, which must be associated together to be properly processed isn’t a good way of doing it.
Instead of doing:
images.append(image) image_paths.append(image_path)
just use images = [] at start, then:
images.append((image,image_path))
then
return images
now your unpacking works fine since each image/path tuple is associated when building the data structure.
