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