J'ai 4 répertoires avec des images pour une animation. J'aimerais prendre l'ensemble des images et générer une seule image avec les 4 images disposées dans une grille 2x2 pour chaque image de l'animation.
Mon code jusqu'ici est:
import Image
fluid64 = "Fluid64_half_size/00"
fluid128 = "Fluid128_half_size/00"
fluid512 = "Fluid512_half_size/00"
fluid1024 = "Fluid1024_half_size/00"
out_image = "Fluid_all/00"
for pic in range(1, 26):
blank_image = Image.open("blank.jpg")
if pic < 10:
image_num = "0"+str(pic)
else:
image_num = str(pic)
image64 = Image.open(fluid64+image_num+".jpg")
image128 = Image.open(fluid128+image_num+".jpg")
image512 = Image.open(fluid512+image_num+".jpg")
image1024 = Image.open(fluid1024+image_num+".jpg")
out = out_image + image_num + ".jpg"
blank_image.paste(image64, (0,0)).paste(fluid128, (400,0)).paste(fluid512, (0,300)).paste(fluid1024, (400,300)).save(out)
Je ne sais pas pourquoi ça ne marche pas. Je reçois l'erreur:
Traceback (most recent call last):
File "C:\Users\Casey\Desktop\Image_composite.py", line 24, in <module>
blank_image.paste(image64, (0,0)).paste(fluid128, (400,0)).paste(fluid512, (
ste(fluid1024, (400,300)).save(out)
AttributeError: 'NoneType' object has no attribute 'paste'
Shell returned 1
Toute aide serait géniale. Merci!
Le seul problème est que "coller" ne retourne pas un objet image - il modifie plutôt l'image "vierge" en place.
Ainsi, lorsque le deuxième collage est appelé (celui qui utilise l'image fuild128), il essaie de s'appliquer sur "Aucun" - qui est la valeur de retour de la première image.
Si c'est le seul problème que vous rencontrez, il suffit de faire un appel coller par ligne, comme ceci:
blank_image.paste(image64, (0,0))
blank_image.paste(fluid128, (400,0))
blank_image.paste(fluid512, (0,300))
blank_image.paste(fluid1024, (400,300))
blank_image.save(out)
Bien qu'il semble probable que vous deviez redimensionner chaque image de manière à ce que leur format corresponde également… .. Et votre code pour la variable "numéro d'image" n'est pas nécessaire. Python est vraiment bon avec les chaînes - faites juste quelque chose comme ça:
image64 = Image.open(fluid64 + "%02d.jpg" % pic)
Vous voudrez peut-être utiliser quelque chose comme:
blank_image = Image.new("RGB", (800, 600))
Cela créera une nouvelle zone en mémoire dans laquelle vous pourrez générer votre image. Vous devriez alors pouvoir coller vos images dans cela.
Ensuite, vous devrez le sauvegarder ultérieurement avec:
blank_image.save("blank.jpg")
Lisez le message d'erreur:
AttributeError: 'NoneType' object has no attribute 'paste'
Cela signifie que vous avez essayé d'appeler .paste
sur quelque chose qui était de type NoneType
, c'est-à-dire sur l'objet None
.
Image.paste
ne renvoie aucun. Vous ne pouvez pas "chaîner" des appels comme celui-ci, sauf lorsque les fonctions sont spécifiquement conçues pour le prendre en charge, alors que Image.paste
ne l’est pas. (La fonction return self
permet d'obtenir ce type de support. Vous obtenez une erreur qui parle de NoneType
car la fonction est écrite pour ne rien retourner, et tout dans Python renvoie None
par défaut si rien d'autre n'est retourné explicitement.) est considéré comme Pythonic: les méthodes renvoient une nouvelle valeur ou modifient self
et renvoient None
. Ainsi, les "interfaces fluides" ne sont pas utilisées lorsque les fonctions ont des effets secondaires - les pythonistes considèrent cela comme néfaste. Retourner None
est un avertissement indiquant que la fonction a des effets secondaires. :)
Il suffit de faire quatre appels .paste
distincts.
Contrairement aux API PIL copy
, crop
, resize
ou rotate
qui renvoient un objet Image
, paste
renvoie None
qui empêche les appels de méthode en chaîne. Pas si pratique _ API design.
Il est facile d'obtenir des chiffres en mosaïque dans une grille 2-sur-2 avec la fonction append_images définie dans cette réponse https://stackoverflow.com/a/46623632/8738113
Par exemple:
img1 = append_images([image64, image128], direction='horizontal')
img2 = append_images([image512, image1024], direction='horizontal')
final = append_images([img1, img2], direction='vertical')
final.save("Fluid_all/00.jpg")