See also our set of HOWTOs.
Will arithmetic overflow?
VIPS operations are value-preserving. VIPS selects the smallest type which can fully represent the range of possible output values. So an 8 bit unsigned image plus an 8 bit unsigned image makes a 16 bit unsigned image. It won't promote past int32, so operations on int images yield int images
Constants are always
double. So 8 bit unsigned image plus constant 2 is a double image.
When you cast an image type down VIPS will warn about overflows (eg. "35698756 pixels overflowed in 16->8 bit cast"), though this isn't usually very helpful.
C++: How do I access the pixel data myself?
VImage fred = whatever ... void *p = fred.data();
This will allocate enough RAM to hold the whole of
fred, render pixel
data into the memory buffer, and return a pointer to the start of the
fred is changed to become a RAM image, so calling
is quick. If you use
jim = fred * 2;
jim will work off the memory data. The memory will be freed when
fred is no longer needed.
It's up to you to cast the result to the correct type. If
fred is an
8-bit unsigned char image, you need to do:
unsigned char *p = (unsigned char *) fred.data();
Images are laid out top to bottom, left to right, pixel-packed (ie. RGBRGBRGB ..), with no line padding.
You must not write to the RAM buffer!! You'll break VIPS's caching. Instead, create a new RAM image and write to that.
How can I process huge images without running out of RAM?
Suppose you want to be able to run:
vips im_shrink hugeimage.tif smallimage.jpg 10 10
To shrink a huge image by a factor of 10 in both directions.
This might or might not run out of memory, it depends on the input image type. VIPS will shrink using (almost) no memory if the input file format supports random access. Random access file formats supported in the current version are:
- tiled tiff, tiff limits the compressed file to 4GB and sometimes to just 2GB
- vips, no filesize limit
- ppm/pbm/pgm, no filesize limit
- raw, no filesize limit
- tiled OpenEXR
If your image is not in one of these formats (eg. line-based TIFF, or PNG), VIPS will unpack the entire image to a memory buffer before processing. This can be slow and will (obviously) use huge amounts of RAM.
If this is not acceptable, you need to convert to a temporary image in a random access format first. I'd recommend VIPS format because it's generally the fastest for large images.
vips im_tiff2vips hugefile.tif hugefile.v vips im_shrink hugefile.v smallfile.jpg 10 10 rm hugefile.v
The conversion will use almost no memory, but will make a
large file on disc. The shrink will now run in very little RAM. Use
im_jpeg2vips etc. for other formats.
You can use a similar trick with C++ or Python programs. The line:
a = VImage.VImage ("hugefile.jpg")
will open a JPEG file, but it will be unpacked to a memory buffer. For large images, this may be unacceptable.
Instead, you can try:
a = VImage.VImage.convert2disc ("im_jpeg2vips", "hugefile.jpg", "temp.v")
Now VIPS will convert the JPEG image to a VIPS image on disc, called
temp.v, and then open that. This will use very little memory, but you are responsible for deleting this temporary image file once you are done with it.
The C API has a new system called
VipsFormat which is a better way to control the details of the image loading process, see the chapter in the VIPS manual. Hopefully this new system will appear in the C++ and Python bindings soon.
What are the issues with shrinking images?
The basic but fast
im_shrink is a simple block average shrinker --- this means it can produce some aliasing when reducing by large factors (eg thumbnail from 3kx2k), but is generally OK for non-critical use. In fact, the small amount of aliasing you get actually looks rather nice.
You can use the affine transform with your choice of interpolators. For example:
vips im_affinei_all big.v small.jpg bicubic 0.9 0 0 0.9 0 0
Will shrink the image by 10%. Use
vips --list classes
To see all the supported interpolators.