7

I have an image which is 6130x5548 pixels and I want to rescale it so that the longest side is 32768 pixels (and then do a pyramid of tiles with 7 zoom levels). I undestand vips resize is the obvious way for something like that, hence I tried the line below

vips resize image_in.tif img_rescaled.tif 5.345513866231648

The number 5.34551 is just the ratio 32768/6130, the scale factor along my x axis. If I want to specify the exact dimensions in pixels of the retured image how can I do that please?

I tried to use vips thumbnail for this purpose, I dont know if this is recommended or not but it does work.

vips thumbnail image_in.tif img_rescaled.tif 32768

Is something like that ok please?

Also the two approaches give quite different outputs in terms of MB size. While vips thumbnail produces a tif with size 2.8Gb the vips resize call returns a tif with size 1.8Gb.

Both images have (obviously) the same dimensions 32768x29657 pixels, same resolution 72dpi but different bit depth The tif from vips thumbnail has 24 bit depth whereas the one from vips resize 16 bit depth. The original image has bit depth=16.

Also, I understand that the algorithm used by vips translate plays a significant role to the resulting file size. Can I set the algorithm when I use vips thumbnail and/or the bit depth please?

Aenaon
  • 3,169
  • 4
  • 32
  • 60
  • Could you explain why you need to upscale by a factor of six before pyramiding? You'll get very blurry pixels. `vipsthumbnail` is supposed to be for making image thumbnails, so it turns most images into sRGB ready for jpeg save. – jcupitt May 24 '19 at 10:56
  • I have around 300K points to plot on the image. You only see a big blob of markers unless you zoom in at something deeper than level 5. Ideally I would like to go as far as level 8, but 7 is a good compromise. The quality also of the background image is not of paramount importance, i can compromise on that as well. Hence I could use `cubic` interpolation instead of `lanczos` which will result in slightly smaller filesize, or even `average`, `nearest` etc which are lot worse in terms of quality but the filesize is also a lot less. – Aenaon May 24 '19 at 11:14
  • Just to expand a bit more on my comment above, If I understand well I can not make 7 zoom levels unless my image is at least `32768 pixels (width or height)`. In this case at level 7 one unit will correspond to 1 pixel. If there is a way to have `units per pixels = 0.5` then scaling up to `16384 pixels` would also be fine for me but I dont think this is possible with `vips` – Aenaon May 24 '19 at 11:33

1 Answers1

8

resize only takes a scale factor, so you need to calculate it. You can use something like:

width=$(vipsheader -f width somefile.tif)
height=$(vipsheader -f height somefile.tif)
size=$((width > height ? width : height))
factor=$(bc <<< "scale=10; 32768 / $size")
vips resize somefile.tif huge.tif $factor

I'd go to 8-bit before upscaling, since you only need 8 bits for the display. You can use:

vips colourspace thing.tif other.tif srgb

To make an 8-bit srgb version.

bash gets so ugly when you start doing stuff like this that I'd be tempted to switch to pyvips.

import pyvips

image = pyvips.Image.new_from_file('somefile.tif', access='sequential')
image = image.colourspace('srgb')
image = image.resize(32768 / max(image.width, image.height))
image.dzsave('mypyramid')

It has the extra advantage that it won't use any temporary files. pyvips builds pipelines of image processing operations, so that program will stream pixels from your input, upsize them, and write the pyramid all at the same time, and all in parallel. It won't use much memory and it'll be quick.

jcupitt
  • 10,213
  • 2
  • 23
  • 39