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.