1.. include global.rst
2
3Introduction
4============
5
6See the main libvips site for an introduction to the underlying library. These
7notes introduce the Python binding.
8
9https://libvips.github.io/libvips
10
11Example
12-------
13
14This example loads a file, boosts the green channel, sharpens the image,
15and saves it back to disc again::
16
17    import pyvips
18
19    image = pyvips.Image.new_from_file('some-image.jpg', access='sequential')
20    image *= [1, 2, 1]
21    mask = pyvips.Image.new_from_array([[-1, -1, -1],
22                                        [-1, 16, -1],
23                                        [-1, -1, -1]
24                                       ], scale=8)
25    image = image.conv(mask, precision='integer')
26    image.write_to_file('x.jpg')
27
28Reading this example line by line, we have::
29
30    image = pyvips.Image.new_from_file('some-image.jpg', access='sequential')
31
32:meth:`.Image.new_from_file` can load any image file supported by libvips.
33When you load an image, only the header is fetched from the file. Pixels will
34not be read until you have built a pipeline of operations and connected it
35to an output.
36
37When you load, you can hint what type of access you will need.  In this
38example, we will be accessing pixels top-to-bottom as we sweep through
39the image reading and writing, so `sequential` access mode is best for us.
40The default mode is ``random`` which allows for full random access to image
41pixels, but is slower and needs more memory. See :class:`.enums.Access`
42for details on the various modes available.
43
44You can also load formatted images from memory with
45:meth:`.Image.new_from_buffer`, create images that wrap C-style memory arrays
46held as Python buffers with :meth:`.Image.new_from_memory`, or make images
47from constants with :meth:`.Image.new_from_array`. You can also create custom
48sources and targets that link image processing pipelines to your own code,
49see `Custom sources and targets`_.
50
51The next line::
52
53    image *= [1, 2, 1]
54
55Multiplies the image by an array constant using one array element for each
56image band. This line assumes that the input image has three bands and will
57double the middle band. For RGB images, that's doubling green.
58
59There is a full set arithmetic operator `Overloads`_, so you can compute with
60entire images just as you would with single numbers.
61
62Next we have::
63
64    mask = pyvips.Image.new_from_array([[-1, -1, -1],
65                                        [-1, 16, -1],
66                                        [-1, -1, -1]
67                                       ], scale = 8)
68    image = image.conv(mask, precision = 'integer')
69
70:meth:`.new_from_array` creates an image from an array constant. The
71scale is the amount to divide the image by after integer convolution.
72
73See the libvips API docs for ``vips_conv()`` (the operation
74invoked by :meth:`.Image.conv`) for details on the convolution operator. By
75default, it computes with a float mask, but ``integer`` is fine for this case,
76and is much faster.
77
78Finally::
79
80    image.write_to_file('x.jpg')
81
82:meth:`.write_to_file` writes an image back to the filesystem. It can
83write any format supported by vips: the file type is set from the filename
84suffix. You can also write formatted images to memory, or dump
85image data to a C-style array in a Python buffer.
86
87Metadata and attributes
88-----------------------
89
90``pyvips`` adds a :meth:`.__getattr__` handler to :class:`.Image` and to
91the Image metaclass, then uses it to look up unknown names in libvips.
92
93Names are first checked against the set of properties that libvips
94keeps for images, see :attr:`.width` and friends. If the name is not
95found there, ``pyvips`` searches the set of libvips operations, see the next
96section.
97
98As well as the core properties, you can read and write the metadata
99that libvips keeps for images with :meth:`.Image.get` and
100friends. For example::
101
102    image = pyvips.Image.new_from_file('some-image.jpg')
103    ipct_string = image.get('ipct-data')
104    exif_date_string = image.get('exif-ifd0-DateTime')
105
106Use :meth:`.get_fields` to get a list of all the field names you can use with
107:meth:`.Image.get`.
108
109libvips caches and shares images between different parts of your program. This
110means that you can't modify an image unless you are certain that you have
111the only reference to it. You can make a private copy of an image with
112``copy``, for example:
113
114        new_image = image.copy(xres=12, yres=13)
115
116Now ``new_image`` is a private clone of ``image`` with ``xres`` and ``yres``
117changed.
118
119Set image metadata with :meth:`.Image.set`. Use :meth:`.Image.copy` to make
120a private copy of the image first, for example::
121
122        new_image = image.copy().set('icc-profile-data', new_profile)
123
124Now ``new_image`` is a clone of ``image`` with a new ICC profile attached to
125it.
126
127NumPy and PIL
128-------------
129
130You can use :meth:`.write_to_memory` and :meth:`.Image.new_from_memory` to pass
131buffers of pixels between PIL, NumPy and pyvips. For example::
132
133    import pyvips
134    import numpy as np
135
136    format_to_dtype = {
137        'uchar': np.uint8,
138        'char': np.int8,
139        'ushort': np.uint16,
140        'short': np.int16,
141        'uint': np.uint32,
142        'int': np.int32,
143        'float': np.float32,
144        'double': np.float64,
145        'complex': np.complex64,
146        'dpcomplex': np.complex128,
147    }
148
149    img = pyvips.Image.new_from_file(sys.argv[1], access='sequential')
150    np_3d = np.ndarray(buffer=img.write_to_memory(),
151                       dtype=format_to_dtype[img.format],
152                       shape=[img.height, img.width, img.bands])
153
154Will make a NumPy array from a vips image. This is a fast way to load many
155image formats.
156
157Going in the other direction, you can write::
158
159    dtype_to_format = {
160        'uint8': 'uchar',
161        'int8': 'char',
162        'uint16': 'ushort',
163        'int16': 'short',
164        'uint32': 'uint',
165        'int32': 'int',
166        'float32': 'float',
167        'float64': 'double',
168        'complex64': 'complex',
169        'complex128': 'dpcomplex',
170    }
171
172    height, width, bands = np_3d.shape
173    linear = np_3d.reshape(width * height * bands)
174    vi = pyvips.Image.new_from_memory(linear.data, width, height, bands,
175                                      dtype_to_format[str(np_3d.dtype)])
176
177To make a vips image that represents a numpy array.
178
179Calling libvips operations
180--------------------------
181
182Unknown names which are not image properties are looked up as libvips
183operations. For example, the libvips operation ``add``, which appears in C as
184``vips_add()``, appears in Python as :meth:`.Image.add`.
185
186The operation's list of required arguments is searched and the first input
187image is set to the value of ``self``. Operations which do not take an input
188image, such as :meth:`.Image.black`, appear as class methods. The
189remainder of the arguments you supply in the function call are used to set
190the other required input arguments. Any trailing keyword arguments are used
191to set options on the underlying libvips operation.
192
193The result is the required output argument if there is only one result,
194or a list of values if the operation produces several results. If the
195operation has optional output objects, they are returned as a final
196Python dictionary.
197
198For example, :meth:`.Image.min`, the vips operation that searches an
199image for the minimum value, has a large number of optional arguments. You
200can use it to find the minimum value like this::
201
202    min_value = image.min()
203
204You can ask it to return the position of the minimum with `:x` and `:y`::
205
206    min_value, opts = image.min(x=True, y=True)
207    x_pos = opts['x']
208    y_pos = opts['y']
209
210Now ``x_pos`` and ``y_pos`` will have the coordinates of the minimum value.
211There's actually a convenience method for this, :meth:`.minpos`.
212
213You can also ask for the top *n* minimum, for example::
214
215    min_value, opts = min(size=10, x_array=True, y_array=True)
216    x_pos = opts['x_array']
217    y_pos = opts['y_array']
218
219Now ``x_pos`` and ``y_pos`` will be 10-element arrays.
220
221Because operations are member functions and return the result image, you can
222chain them. For example, you can write::
223
224    result_image = image.real().cos()
225
226to calculate the cosine of the real part of a complex image.  There is
227also a full set of arithmetic `Overloads`_.
228
229libvips types are automatically wrapped. The binding looks at the type
230of argument required by the operation and converts the value you supply,
231when it can. For example, :meth:`.Image.linear` takes a
232``VipsArrayDouble`` as an argument for the set of constants to use for
233multiplication. You can supply this value as an integer, a float, or some
234kind of compound object and it will be converted for you. You can write::
235
236    result_image = image.linear(1, 3)
237    result_image = image.linear(12.4, 13.9)
238    result_image = image.linear([1, 2, 3], [4, 5, 6])
239    result_image = image.linear(1, [4, 5, 6])
240
241And so on. A set of overloads are defined for :meth:`.Image.linear`,
242see below.
243
244If an operation takes several input images, you can use a constant for all but
245one of them and the wrapper will expand the constant to an image for you. For
246example, :meth:`.ifthenelse` uses a condition image to pick pixels
247between a then and an else image::
248
249    result_image = condition_image.ifthenelse(then_image, else_image)
250
251You can use a constant instead of either the then or the else parts and it
252will be expanded to an image for you. If you use a constant for both then and
253else, it will be expanded to match the condition image. For example::
254
255    result_image = condition_image.ifthenelse([0, 255, 0], [255, 0, 0])
256
257Will make an image where true pixels are green and false pixels are red.
258
259This is useful for :meth:`.bandjoin`, the thing to join two or more
260images up bandwise. You can write::
261
262    rgba = rgb.bandjoin(255)
263
264to append a constant 255 band to an image, perhaps to add an alpha channel. Of
265course you can also write::
266
267    result_image = image1.bandjoin(image2)
268    result_image = image1.bandjoin([image2, image3])
269    result_image = pyvips.Image.bandjoin([image1, image2, image3])
270    result_image = image1.bandjoin([image2, 255])
271
272and so on.
273
274Logging and warnings
275--------------------
276
277The module uses ``logging`` to log warnings from libvips, and debug messages
278from the module itself. Some warnings are important, for example truncated
279files, and you might want to see them.
280
281Add these lines somewhere near the start of your program::
282
283        import logging
284        logging.basicConfig(level=logging.WARNING)
285
286
287Exceptions
288----------
289
290The wrapper spots errors from vips operations and raises the :class:`.Error`
291exception. You can catch it in the usual way.
292
293Enums
294-----
295
296The libvips enums, such as ``VipsBandFormat``, appear in pyvips as strings
297like ``'uchar'``. They are documented as a set of classes for convenience, see
298:class:`.Access`, for example.
299
300Overloads
301---------
302
303The wrapper defines the usual set of arithmetic, boolean and relational
304overloads on image. You can mix images, constants and lists of constants
305freely. For example, you can write::
306
307    result_image = ((image * [1, 2, 3]).abs() < 128) | 4
308
309Expansions
310----------
311
312Some vips operators take an enum to select an action, for example
313:meth:`.Image.math` can be used to calculate sine of every pixel
314like this::
315
316    result_image = image.math('sin')
317
318This is annoying, so the wrapper expands all these enums into separate members
319named after the enum value. So you can also write::
320
321    result_image = image.sin()
322
323Convenience functions
324---------------------
325
326The wrapper defines a few extra useful utility functions:
327:meth:`.bandsplit`, :meth:`.maxpos`, :meth:`.minpos`,
328:meth:`.median`.
329
330Tracking and interrupting computation
331-------------------------------------
332
333You can attach progress handlers to images to watch the progress of
334computation.
335
336For example::
337
338    image = pyvips.Image.black(1, 500)
339    image.set_progress(True)
340    image.signal_connect('preeval', preeval_handler)
341    image.signal_connect('eval', eval_handler)
342    image.signal_connect('posteval', posteval_handler)
343    image.avg()
344
345Handlers are given a `progress` object containing a number of useful fields.
346For example::
347
348   def eval_handler(image, progress):
349       print('run time so far (secs) = {}'.format(progress.run))
350       print('estimated time of arrival (secs) = {}'.format(progress.eta))
351       print('total number of pels to process = {}'.format(progress.tpels))
352       print('number of pels processed so far = {}'.format(progress.npels))
353       print('percent complete = {}'.format(progress.percent))
354
355Use :meth:`.Image.set_kill` on the image to stop computation early.
356
357For example::
358
359   def eval_handler(image, progress):
360       if progress.percent > 50:
361           image.set_kill(True)
362
363Custom sources and targets
364--------------------------
365
366You can load and save images to and from :class:`.Source` and
367:class:`.Target`.
368
369For example::
370
371   source = pyvips.Source.new_from_file("some/file/name")
372   image = pyvips.Image.new_from_source(source, "", access="sequential")
373   target = pyvips.Target.new_to_file("some/file/name")
374   image.write_to_target(target, ".png")
375
376Sources and targets can be files, descriptors (eg. pipes) and areas of memory.
377
378You can define :class:`.SourceCustom` and :class:`.TargetCustom` too.
379
380For example::
381
382   input_file = open(sys.argv[1], "rb")
383
384   def read_handler(size):
385       return input_file.read(size)
386
387   source = pyvips.SourceCustom()
388   source.on_read(read_handler)
389
390   output_file = open(sys.argv[2], "wb")
391
392   def write_handler(chunk):
393       return output_file.write(chunk)
394
395   target = pyvips.TargetCustom()
396   target.on_write(write_handler)
397
398   image = pyvips.Image.new_from_source(source, '', access='sequential')
399   image.write_to_target(target, '.png')
400
401You can also define seek and finish handlers, see the docs.
402
403Automatic documentation
404-----------------------
405
406The bulk of these API docs are generated automatically by
407:meth:`.Operation.generate_sphinx_all`. It examines libvips and writes a
408summary of each operation and the arguments and options that that operation
409expects.
410
411Use the C API docs for more detail:
412
413https://libvips.github.io/libvips/API/current
414
415Draw operations
416---------------
417
418Paint operations like :meth:`.Image.draw_circle` and
419:meth:`.Image.draw_line` modify their input image. This makes them
420hard to use with the rest of libvips: you need to be very careful about
421the order in which operations execute or you can get nasty crashes.
422
423The wrapper spots operations of this type and makes a private copy of the
424image in memory before calling the operation. This stops crashes, but it does
425make it inefficient. If you draw 100 lines on an image, for example, you'll
426copy the image 100 times. The wrapper does make sure that memory is recycled
427where possible, so you won't have 100 copies in memory.
428
429If you want to avoid the copies, you'll need to call drawing operations
430yourself.
431
432