Create Vips Image from Numpy RGB array for big images

Question:

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
Asked By: Kingsley

||

Answers:

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")
Answered By: jcupitt
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.