0

I'm trying to join multiple images together using pyvips, but during the process the width of the image more than doubles, and I can't seem to figure out why

Here's the key part of my code:

files = ['small_images\\'+filename for filename in os.listdir('small_images')]
files = natsorted(files)

images = [pyvips.Image.new_from_file(filename, access="sequential") for filename in files]
[print(f'width: {image.width}, height: {image.height}') for image in images]

raster = pyvips.Image.arrayjoin(images,across=len(images))
print(f'raster width: {raster.width}, raster height: {raster.height}')

raster.write_to_file(f'rasters.png')

Expected output for 5 files should be:

width: 115, height: 1449

width: 44, height: 1449

width: 226, height: 1449

width: 74, height: 1449

width: 35, height: 1449

raster width: 494, raster height: 1449

But my actual output is:

width: 115, height: 1449

width: 44, height: 1449

width: 226, height: 1449

width: 74, height: 1449

width: 35, height: 1449

raster width: 1130, raster height: 1449

Images: https://i.stack.imgur.com/bCqPV.jpg

What's causing this?

Jayleaf
  • 31
  • 1
  • 9
  • 1
    Please show your images - does one maybe have a different height? – Mark Setchell Dec 18 '19 at 16:45
  • you don't have to use prefix `f` in strings if you don't use variables like `{filename}` inside strings – furas Dec 18 '19 at 16:57
  • @MarkSetchell Yes, they vary in height by up to 50px, from 1400px to 1450px. Why would this cause them to be stretched horizontally? – Jayleaf Dec 18 '19 at 17:00
  • 1
    For the moment, I can only guess because I can't see your images. – Mark Setchell Dec 18 '19 at 17:17
  • @MarkSetchell Here's the image sample, I've updated them to all be the same height to eliminate that being a potential issue: https://imgur.com/a/IDuRtIK – Jayleaf Dec 18 '19 at 17:24
  • I can't see what would cause that behaviour, and if it is any consolation, **ImageMagick** will do it correctly from the command line with `magick *png +append result.png` The only odd thing I see is that the image that is 226 pixels wide is PaletteAlpha whereas the others are bi-level - I still don't know why that would make difference though. – Mark Setchell Dec 18 '19 at 17:38

1 Answers1

2

arrayjoin only does regular grids of images -- it'll pick the maximum width and height in your set of images, and that becomes the spacing. It's like a table layout.

If you want to join a series of images of varying width left to right, you need to do a series of joins. For example:

output = images[0]
for image in images[1:]:
    output = output.join(image, 'horizontal', expand=True)

You can set alignment, spacing, background, etc., see:

https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-join

jcupitt
  • 10,213
  • 2
  • 23
  • 39