1.3 The VImage class

The VImage class is a layer over the VIPS IMAGE type. It automates almost all of the image creation and destruction issues that complicate the C API, it automates error handling, and it provides a convenient system for composing operations.

1.3.1 Constructors

There are two principal constructors for VImage:

VImage::VImage( const char ⋆name,  
  const char ⋆mode = "r" );  
VImage::VImage();

The first form creates a new VImage, linking it to the named file. mode sets the mode for the file: it can take the following values:

"r"
The named image file is opened read-only. This is the default mode.
"w"
A VImage is created which, when written to, will write pixels to disc in the specified file. Any existing file of this name is deleted.
"t"
As the "w" mode, but pixels written to the VImage will be saved in a temporary memory buffer.
"p"
This creates a special ‘partial’ image. Partial images represent intermediate results, and are used to join VIPS operations together, see §1.3.5.
"rw"
As the "r" mode, but the image is mapped into your address space read-write. This mode is useful for paintbox-style applications which need to directly modify an image. See §4.2.8.

The second form of constructor is shorthand for:

VImage( "VImage:1", "p" )

It is used for representing intermediate results of computations.

Two further constructors are handy for wrapping VImage around existing images.

VImage( void ⋆buffer,  
  int width, int height, int bands,  
  TBandFmt format );  
VImage( void ⋆image );

The first constructor makes a VImage from an area of memory (perhaps from another image processing system), and the second makes a VImage from an IMAGE.

In both these two cases, the VIPS C++ API does not assume responsibility for the resources: it’s up to you to make sure the buffer is freed.

The Python interface adds the usual frombuffer and fromstring methods.

VImage.fromstring (string,  
  width, height, bands, format) ->  
  VImage

VImage.frombuffer (buffer,  
  width, height, bands, format) ->  
  VImage

Use fromstring to avoid worries about object lifetime, but you’ll see a lot of copies and high memory use. Use frombuffer for speed, but you have to manage object lifetime yourself.

They are useful for moving images into VIPS from other image processing libraries. There’s also a utility function, vips_from_PIL_mode, which turns a PIL mode into a VIPS band, format, type triple.

VImage.vips_from_PIL_mode (mode) ->  
  (bands, format, type)

See also tobuffer and tostring below.

1.3.2 File conversion

VIPS can read and write a number of different file formats. Information about file format conversion is taken from the filename. For example:

VImage jim( "fred.jpg" );

This will decompress the file fred.jpg to a memory buffer, wrap a VIPS image around the buffer and build a reference to it called jim.

Options are passed to the file format converters embedded in the filename. For example:

VImage out( "jen.tif:deflate", "w" );

Writing to the descriptor out will cause a TIFF image to be written to disc with deflate compression.

See the manual page for im_open(3) for details of all the file formats and conversions available. See the man page for VipsFormat(3) for a lower-level API which lets you control more of the detail of reading and writing data and is more suitable for large files.

1.3.3 Projection functions

A set of member functions of VImage provide access to the fields in the header:

int Xsize();  
int Ysize();  
int Bands();  
TBandFmt BandFmt();  
TCoding Coding();  
TType Type();  
float Xres();  
float Yres();  
int Length();  
TCompression Compression();  
short Level();  
int Xoffset();  
int Yoffset();

Where TBandFmt, TCoding, TType and TCompression are enums for the types in the VIPS file header. See section §1.2.1 for an explanation of all of these fields.

Two functions give access to the filename and history fields maintained by the VIPS IO system.

char ⋆filename();  
char ⋆Hist();

You can get and set extra metadata fields with meta_get() and meta_set(). They read and write GValue objects, see §2.2.6.

void meta_set( const char ⋆field, GValue ⋆value );  
void meta_get( const char ⋆field, GValue ⋆value_copy );  
GType meta_get_type( const char ⋆field );

A set of convenience functions build on these two to provide accessors for common types.

int meta_get_int( const char ⋆field )  
double meta_get_double( const char ⋆field )  
const char ⋆meta_get_string( const char ⋆field )  
void ⋆meta_get_area( const char ⋆field )  
void ⋆meta_get_blob( const char ⋆field, size_t ⋆length )  
 
void meta_set( const char ⋆field, int value )  
void meta_set( const char ⋆field, double value )  
void meta_set( const char ⋆field, const char ⋆value )  
void meta_set( const char ⋆field,  
VCallback free_fn, void ⋆value )  
void meta_set( const char ⋆field,  
VCallback free_fn, void ⋆value, size_t length )

The image() member function provides access to the IMAGE descriptor underlying the C++ API. See the §2.1 for details.

void ⋆image();

The data() member function returns a pointer to an array of pixel data for the image.

void ⋆data() const;

This can be very slow and use huge amounts of RAM.

The Python interface adds tobuffer and tostring. These operations call data() to generate the image pixels and then either copy it and return the copy as a string, or wrap the pixels up as a Python buffer object.

Use tostring to avoid worries about object lifetime, but you’ll see a lot of copies and high memory use. Use tobuffer for speed, but you have to manage object lifetime yourself.

They are useful for moving images from VIPS into other image processing libraries. There’s also a utility function, PIL_mode_from_vips, which makes a PIL mode from a VIPS image.

VImage.PIL_mode_from_vips (vips-image) ->  
  mode

See also frombuffer and fromstring above.

1.3.4 Assignment

VImage defines copy and assignment, with reference-counted, pointer-style semantics. For example, if you write:

VImage fred( "fred.v" );  
VImage jim( "jim.v" );  
 
fred = jim;

This will automatically close the file fred.v, and make the variable fred point to the image jim.v instead. Both jim and fred now point to the same underlying image object.

Internally, a VImage object is just a pointer to a reference-counting block, which in turn holds a pointer to the underlying VIPS IMAGE type. You can therefore efficiently pass VImage objects to functions by value, and return VImage objects as function results.

1.3.5 Computing with VImages

All VIPS image processing operations are member functions of the VImage class. For example:

VImage fred( "fred.v" );  
VImage jim( "jim.v" );  
 
VImage result = fred.cos() + jim;

Will apply im_costra() to fred.v, making an image where each pixel is the cosine of the corresponding pixel in fred.v; then add that image to jim.v. Finally, the result will be held in result.

VIPS is a demand-driven image processing system: when it computes expressions like this, no actual pixels are calculated (although you can use the projection functions on images — result.BandFmt() for example). When you finally write the result to a file (or use some operation that needs pixel values, such as min(), find minimum value), VIPS evaluates all of the operations you have called to that point in parallel. If you have more than one CPU in your machine, the load is spread over the available processors. This means that there is no limit to the size of the images you can process.

§4.2 lists all of the VIPS packages. These general rules apply:

This part of the C++ API is generated automatically from the VIPS function database, so it should all be up-to-date.

There are a set of arithmetic operators defined for your convenience. You can generally write any arithmetic expression and include VImage in there.

VImage fred( "fred.v" );  
VImage jim( "jim.v" );  
 
Vimage v = int((fred + jim) / 2);

1.3.6 Writing results

Once you have computed some result, you can write it to a file with the member write(). It takes the following forms:

VImage write( const char ⋆name );  
VImage write( VImage out );  
VImage write();

The first form simply writes the image to the named file. The second form writes the image to the specified VImage object, for example:

VImage fred( "fred.v" );  
VImage jim( "jim buffer", "t" );  
 
Vimage v = (fred + 42).write( jim );

This creates a temporary memory buffer called jim, and fills it with the result of adding 42 to every pixel in fred.v.

The final form of write() writes the image to a memory buffer, and returns that.

1.3.7 Type conversions

Two type conversions are defined: you can cast VImage to a VDMask and to a VIMask.

operator VDMask();  
operator VIMask();

These operations are slow and need a lot of memory! Emergencies only.