I was trying to output a large, generated image with PIL/Pillow, but it breaks when the image sizes get bigger.
So based on things I read on SO, I'm trying to use Vips.
My generated data is a numpy array of RGB values. I want to convert this to a image in Vips so I can save it. However I cannot work out how to get the pixel data into Vips.
import numpy
import gi
gi.require_version('Vips', '8.0')
from gi.repository import Vips
WIDTH=32768
HEIGHT=32768
UCHAR=Vips.BandFormat.UCHAR
# Create an RGB black image
black_space = numpy.zeros( ( WIDTH, HEIGHT, 3 ), dtype=numpy.uint8 )
# this doesn't work
vips_image = Vips.Image.new_from_memory( black_space, WIDTH, HEIGHT, bands=3, format=UCHAR )
vips_image.write_to_file( "space_32k.tiff" )
Of course it fails with the error when creating the Vips image:
Traceback (most recent call last):
File "./bad_vips.py", line 14, in <module>
vips_image = Vips.Image.new_from_memory( black_space, WIDTH, HEIGHT, bands=3, format=UCHAR )
TypeError: Item 0: expected int argument
Is there a way of transforming the numpy array so it works with Vips?
I also tried passing black_space.data
, but then I get:
NotImplementedError: Item 0: multi-dimensional sub-views are not implemented
You're using the old libvips Python interface -- there's a newer one now which is quite a bit better:
https://github.com/libvips/pyvips
Docs here:
https://libvips.github.io/pyvips/
There's a section about linking libvips and numpy. Your example would be:
import numpy as np
import pyvips
array = np.zeros((100, 100, 3), dtype=np.uint8)
image = pyvips.Image.new_from_array(array)
image.write_to_file("huge.tif")