Reputation: 4049
I'm playing around with regenerative art using Python and the Pillow library. I've got multiple directories with images, my goal is to use the Pillow library to create 'collages'.
I'm loading images into arrays this like this:
#load img files into an array
skin = [file for file in os.listdir('skin') if file.endswith('.png')]
hair = [file for file in os.listdir('hair') if file.endswith('.png')]
head = [file for file in os.listdir('head') if file.endswith('.png')]
mouth = [file for file in os.listdir('mouth') if file.endswith('.png')]
nose = [file for file in os.listdir('nose') if file.endswith('.png')]
eyes = [file for file in os.listdir('eyes') if file.endswith('.png')]
#select a random image from each array
skin_img = random.choices(skin)[0]
hair_img = random.choices(hair)[0]
head_img = random.choices(head)[0]
mouth_img = random.choices(mouth)[0]
nose_img = random.choices(nose)[0]
eyes_img = random.choices(eyes)[0]
I want to layer/merge these in a specific order, I'm hoping I can accomplish this using an array, like this:
order = ['head','skin','mouth','eyes','nose','hair']
Using the Pillow library, one can merge. two images like this:
img1 = Image.open(head_img)
img2 = Image.open(skin_img)
comp1 = Image.alpha_composite(img1,img2)
My question: How can I loop through the order array and merge all of my images, ending up with a single composite?
Upvotes: 0
Views: 1493
Reputation: 2439
I think I have an idea what are you doing. But I don't know if this is the best way. Nonetheless I am going to answer the question as good as I can.
Note: It might not be most efficient way.
Our face parts are:
parts = ['head', 'skin', 'mouth', 'eyes', 'nose', 'hair']
Now let's get files lists in a dictionary as such:
{
"head": ["f1", "f2", ...],
"skin": ["s1", "s2", ...],
"mouth": ["m1", "m2", ...],
"eyes": ["e1", "e2", ...],
"nose": ["n1", "n2", ...],
"hair": ["h1", "h2", ...]
}
I am not going to change your way of doing it, but would highly recommend you to obtain file paths using glob
.
files = {
part: [file for file in os.listdir(part) if file.endswith('.png')]
for part in parts
}
Now we have file paths/names to process.
Next let's get the face image and put it in final_image
. We will combine other images with this one.
final_image = Image.open(random.choice(files["head"]))
I see you were getting random.choices
and were getting the first element:
random.choices(skin)[0]
But you can get random.choice
of a list. And it will return one element.
Now let loop in our dictionary and get a random element of each face part and combine it by the final_image
. Of course except the "face"
for key, value in files.items():
if key != "head":
part_image = Image.open(random.choice(value))
final_image = Image.alpha_composite(final_image, part_image)
Now you have what you are looking for.
The final code would be:
parts = ['head', 'skin', 'mouth', 'eyes', 'nose', 'hair']
files = {
part: [file for file in os.listdir(part) if file.endswith('.png')]
for part in parts
}
final_image = Image.open(random.choice(files["head"]))
for key, value in files.items():
if key != "head":
part_image = Image.open(random.choice(value))
final_image = Image.alpha_composite(final_image, part_image)
Upvotes: 1