Estoy tratando de combinar horizontalmente algunas imágenes JPEG en Python.
Problema
Tengo 3 imágenes - cada una mide 148 x 95 - ver adjunto. Acabo de hacer 3 copias de la misma imagen, por eso son iguales.
Mi intento
Estoy tratando de unirlos horizontalmente usando el siguiente código:
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')
Sin embargo, esto produce la salida adjunta como test.jpg
.
Pregunta
¿Hay alguna forma de concatenar horizontalmente estas imágenes de modo que las subimágenes en test.jpg no muestren una imagen parcial adicional?
Información Adicional
Estoy buscando una forma de concatenar horizontalmente n imágenes. Me gustaría usar este código en general, así que preferiría:
- no codificar las dimensiones de la imagen, si es posible
- especificar dimensiones en una línea para que se puedan cambiar fácilmente
for i in xrange(...)
en su código? ¿No deberíapaste
ocuparse de los tres archivos de imagen que especifica?Respuestas:
Puedes hacer algo como esto:
Test1.jpg
Test2.jpg
Test3.jpg
test.jpg
El anidado
for i in xrange(0,444,95):
es pegar cada imagen 5 veces, escalonadas a 95 píxeles de distancia. Cada iteración del bucle externo se pega sobre la anterior.fuente
x_offset = 0
- ¿Es este el escalonamiento entre los centros de imagen? 2. Para una concatenación vertical, ¿cómo cambia su enfoque?x_offset
comoleft
. Para concat vertical, realice un seguimiento dey-offset
, otop
. En lugar desum(widths)
ymax(height)
, hagasum(heights)
ymax(widths)
utilice el segundo argumento del cuadro de 2 tuplas. Incrementary_offset
porim.size[1]
.map
en python3.6Probaría esto:
Debería funcionar siempre que todas las imágenes sean de la misma variedad (todas RGB, todas RGBA o todas en escala de grises). No debería ser difícil asegurarse de que este sea el caso con algunas líneas más de código. Aquí están mis imágenes de ejemplo y el resultado:
Test1.jpg
Test2.jpg
Test3.jpg
Trifecta.jpg:
Trifecta_vertical.jpg
fuente
min_shape =....
yimgs_comb....
por una concatenación vertical? ¿Podrías publicar eso aquí como comentario o en tu respuesta?hstack
avstack
.Image.resize
del PIL.min_shape
es una tupla de (min_width, min_height) y luego(np.asarray( i.resize(min_shape) ) for i in imgs )
encogerá todas las imágenes a ese tamaño. De hecho,min_shape
puede ser cualquiera(width,height)
que desee, solo tenga en cuenta que ampliar las imágenes de baja resolución las hará borrosas.Editar: la respuesta de DTing es más aplicable a su pregunta ya que usa PIL, pero dejaré esto en caso de que quiera saber cómo hacerlo en numpy.
Aquí hay una solución numpy / matplotlib que debería funcionar para N imágenes (solo imágenes en color) de cualquier tamaño / forma.
Aquí hay un ejemplo de uso:
fuente
output = concat_images(output, ...
es lo que estaba buscando cuando comencé a buscar una forma de hacer esto. Gracias.Basado en la respuesta de DTing, creé una función que es más fácil de usar:
Permite elegir un color de fondo y la alineación de la imagen. También es fácil hacer recursividad:
fuente
Aquí hay una función que generaliza enfoques anteriores, creando una cuadrícula de imágenes en PIL:
Reducirá cada fila y columna de la cuadrícula al mínimo. Puede tener solo una fila usando pil_grid (imágenes), o solo una columna usando pil_grid (imágenes, 1).
Un beneficio de usar PIL sobre las soluciones basadas en matrices numpy es que puede manejar imágenes estructuradas de manera diferente (como imágenes en escala de grises o basadas en paletas).
Salidas de ejemplo
pil_grid(dummy_images)
:pil_grid(dummy_images, 3)
:pil_grid(dummy_images, 1)
:fuente
h_sizes, v_sizes = [0] * n_horiz, [0] * (n_images // n_horiz)
debería leer:h_sizes, v_sizes = [0] * n_horiz, [0] * ((n_images // n_horiz) + (1 if n_images % n_horiz > 0 else 0))
Razón: Si el ancho horizontal no divide el número de imágenes en números enteros, debe acomodar la línea adicional si está incompleta.Si todas las alturas de la imagen son iguales,
tal vez puedas cambiar el tamaño de las imágenes antes de la concatenación de esta manera,
fuente
Esta es mi solución:
Para estas imágenes:
Los resultados se verán así:
fuente
fuente
Salida
fuente
Simplemente agregando a las soluciones ya sugeridas. Asume la misma altura, sin cambiar el tamaño.
fuente
mi solución sería:
fuente