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.