J'essaie de combiner horizontalement certaines images JPEG en Python.
Problème
J'ai 3 images - chacune mesure 148 x 95 - voir ci-joint. Je viens de faire 3 copies de la même image - c'est pourquoi elles sont identiques.
Ma tentative
J'essaye de les joindre horizontalement en utilisant le code suivant:
import sys
from PIL import Image
list_im = ['Test1.jpg','Test2.jpg','Test3.jpg']
new_im = Image.new('RGB', (444,95)) #creates a new empty image, RGB mode, and size 444 by 95
for elem in list_im:
for i in xrange(0,444,95):
im=Image.open(elem)
new_im.paste(im, (i,0))
new_im.save('test.jpg')
Cependant, cela produit la sortie jointe en tant que test.jpg
.
Question
Existe-t-il un moyen de concaténer horizontalement ces images de telle sorte que les sous-images dans test.jpg n'aient pas une image partielle supplémentaire?
Information additionnelle
Je cherche un moyen de concaténer horizontalement n images. J'aimerais utiliser ce code de manière générale donc je préférerais:
- ne pas coder en dur les dimensions de l'image, si possible
- spécifier les dimensions sur une ligne afin qu'elles puissent être facilement modifiées
for i in xrange(...)
dans votre code? Vous ne devriez pas vouspaste
occuper des trois fichiers image que vous spécifiez?Réponses:
Vous pouvez faire quelque chose comme ceci:
Test1.jpg
Test2.jpg
Test3.jpg
test.jpg
Le imbriqué pour
for i in xrange(0,444,95):
colle chaque image 5 fois, décalés de 95 pixels. Chaque itération de boucle externe collée sur la précédente.la source
x_offset = 0
- est-ce le décalage entre les centres d'images? 2. Pour une concaténation verticale, comment votre approche change-t-elle?x_offset
asleft
. Pour un concat vertical, gardez une trace duy-offset
, outop
. Au lieu desum(widths)
andmax(height)
, faitessum(heights)
etmax(widths)
et utilisez le deuxième argument de la boîte à 2 tuples. incrémentery_offset
deim.size[1]
.map
python3.6J'essaierais ceci:
Cela devrait fonctionner tant que toutes les images sont de la même variété (toutes RVB, toutes RVBA ou toutes niveaux de gris). Il ne devrait pas être difficile de s'assurer que c'est le cas avec quelques lignes de code supplémentaires. Voici mes images d'exemple et le résultat:
Test1.jpg
Test2.jpg
Test3.jpg
Trifecta.jpg:
Trifecta_vertical.jpg
la source
min_shape =....
etimgs_comb....
changer pour une concaténation verticale? Pourriez-vous publier cela ici en commentaire ou dans votre réponse?hstack
àvstack
.Image.resize
de PIL.min_shape
est un tuple de (min_width, min_height) et(np.asarray( i.resize(min_shape) ) for i in imgs )
réduira ensuite toutes les images à cette taille. En fait, celamin_shape
peut être tout(width,height)
ce que vous désirez, gardez simplement à l'esprit que l'agrandissement des images basse résolution les rendra floues!Edit: La réponse de DTing est plus applicable à votre question car elle utilise PIL, mais je laisserai cela au cas où vous voudriez savoir comment le faire dans numpy.
Voici une solution numpy / matplotlib qui devrait fonctionner pour N images (uniquement des images couleur) de toute taille / forme.
Voici un exemple d'utilisation:
la source
output = concat_images(output, ...
est ce que je cherchais quand je commencé à chercher un moyen de le faire. Merci.Sur la base de la réponse de DTing, j'ai créé une fonction plus simple à utiliser:
Il permet de choisir une couleur de fond et un alignement d'image. Il est également facile de faire de la récursivité:
la source
Voici une fonction généralisant les approches précédentes, créant une grille d'images en PIL:
Cela réduira au minimum chaque ligne et colonne de la grille. Vous ne pouvez avoir qu'une ligne en utilisant pil_grid (images), ou seulement une colonne en utilisant pil_grid (images, 1).
L'un des avantages de l'utilisation de PIL par rapport aux solutions basées sur numpy-array est que vous pouvez traiter des images structurées différemment (comme des images en niveaux de gris ou en palette).
Exemples de sorties
pil_grid(dummy_images)
:pil_grid(dummy_images, 3)
:pil_grid(dummy_images, 1)
:la source
h_sizes, v_sizes = [0] * n_horiz, [0] * (n_images // n_horiz)
doit se lire:h_sizes, v_sizes = [0] * n_horiz, [0] * ((n_images // n_horiz) + (1 if n_images % n_horiz > 0 else 0))
Raison: Si la largeur horizontale ne divise pas le nombre d'images en nombres entiers, vous devez tenir compte de la ligne supplémentaire si incomplète.Si toutes les hauteurs d'image sont identiques,
peut-être que vous pouvez redimensionner les images avant la concaténation comme ceci,
la source
Voici ma solution:
Pour ces images:
Les résultats ressembleront à:
la source
la source
Production
la source
Il suffit d'ajouter aux solutions déjà proposées. Suppose la même hauteur, pas de redimensionnement.
la source
ma solution serait:
la source