• Stars
    star
    638
  • Rank 70,537 (Top 2 %)
  • Language
    Python
  • License
    MIT License
  • Created over 7 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

python binding for libvips using cffi

README

Build Status

PyPI package:

https://pypi.python.org/pypi/pyvips

conda package:

https://anaconda.org/conda-forge/pyvips

We have formatted docs online here:

https://libvips.github.io/pyvips/

This module wraps the libvips image processing library:

https://libvips.github.io/libvips/

The libvips docs are also very useful:

https://libvips.github.io/libvips/API/current/

If you have the development headers for libvips installed and have a working C compiler, this module will use cffi API mode to try to build a libvips binary extension for your Python.

If it is unable to build a binary extension, it will use cffi ABI mode instead and only needs the libvips shared library. This takes longer to start up and is typically ~20% slower in execution. You can find out how pyvips installed with pip show pyvips.

This binding passes the vips test suite cleanly and with no leaks under python2.7 - python3.11, pypy and pypy3 on Windows, macOS and Linux.

How it works

Programs that use pyvips don't manipulate images directly, instead they create pipelines of image processing operations building on a source image. When the end of the pipe is connected to a destination, the whole pipeline executes at once, streaming the image in parallel from source to destination a section at a time.

Because pyvips is parallel, it's quick, and because it doesn't need to keep entire images in memory, it's light. For example, the libvips speed and memory use benchmark:

https://github.com/libvips/libvips/wiki/Speed-and-memory-use

Loads a large tiff image, shrinks by 10%, sharpens, and saves again. On this test pyvips is typically 3x faster than ImageMagick and needs 5x less memory.

There's a handy chapter in the docs explaining how libvips opens files, which gives some more background.

http://libvips.github.io/libvips/API/current/How-it-opens-files.md.html

Install

You need the libvips shared library on your library search path, version 8.2 or later, though at least version 8.9 is required for all features to work. See:

https://libvips.github.io/libvips/install.html

Linux install

Perhaps:

$ sudo apt install libvips-dev --no-install-recommends
$ pip install pyvips

With python 3.11 and later, you will need to create a venv first and add path/to/venv to your PATH. Something like:

$ python3 -m venv ~/.local
$ pip install pyvips

macOS install

With homebrew:

$ brew install vips python pkg-config
$ pip3 install pyvips

Windows install

on Windows you can download a pre-compiled binary from the libvips website.

https://libvips.github.io/libvips/install.html

You'll need a 64-bit Python. The official one works well.

You can add vips-dev-x.y\bin to your PATH, but this will add a lot of extra DLLs to your search path and they might conflict with other programs, so it's usually safer to set PATH in your program.

To set PATH from within Python, you need something like this at the start of your program:

import os
vipsbin = r'c:\vips-dev-8.13\bin'
os.environ['PATH'] = vipsbin + ';' + os.environ['PATH']

For Python 3.8 and later, you need:

import os
vipsbin = r'c:\vips-dev-8.13\bin'
add_dll_dir = getattr(os, 'add_dll_directory', None)
if callable(add_dll_dir):
    add_dll_dir(vipsbin)
else:
    os.environ['PATH'] = os.pathsep.join((vipsbin, os.environ['PATH']))

Now when you import pyvips, it should be able to find the DLLs.

conda install

The conda package includes a matching libvips binary, so just enter:

$ conda install --channel conda-forge pyvips

Example

This sample program loads a JPG image, doubles the value of every green pixel, sharpens, and then writes the image back to the filesystem again:

import pyvips

image = pyvips.Image.new_from_file('some-image.jpg', access='sequential')
image *= [1, 2, 1]
mask = pyvips.Image.new_from_array([
    [-1, -1, -1],
    [-1, 16, -1],
    [-1, -1, -1],
], scale=8)
image = image.conv(mask, precision='integer')
image.write_to_file('x.jpg')

Notes

Local user install:

$ pip3 install -e .
$ pypy -m pip --user -e .

Run all tests:

$ tox 

Run test suite:

$ pytest

Run a specific test:

$ pytest tests/test_saveload.py

Run perf tests:

$ cd tests/perf
$ ./run.sh

Stylecheck:

$ flake8

Generate HTML docs in doc/build/html:

$ cd doc; sphinx-build -bhtml . build/html

Regenerate enums:

Make sure you have installed a libvips with all optional packages enabled, then

$ cd examples; \
  ./gen-enums.py ~/GIT/libvips/libvips/Vips-8.0.gir > enums.py

Then check and move enums.py into pyvips/.

Regenerate autodocs:

Make sure you have installed a libvips with all optional packages enabled, then

$ cd doc; \
  python3 -c "import pyvips; pyvips.Operation.generate_sphinx_all()" > x 

And copy-paste x into the obvious place in doc/vimage.rst.

Update version number:

$ vi pyvips/version.py
$ vi doc/conf.py

Update pypi package:

$ python3 setup.py sdist
$ twine upload --repository pyvips dist/*
$ git tag -a v2.2.0 -m "as uploaded to pypi"
$ git push origin v2.2.0