{"id":5445,"library":"pyvips","title":"pyvips: Python binding for libvips","description":"pyvips is a Python binding for the high-performance libvips image processing library. It is designed for speed and low memory usage, particularly when handling large images, by employing a streaming, parallel processing pipeline that avoids loading entire images into memory. The library is actively maintained and supports Python versions 3.7 and newer.","status":"active","version":"3.1.1","language":"en","source_language":"en","source_url":"https://github.com/libvips/pyvips","tags":["image processing","image manipulation","libvips","performance","computer vision"],"install":[{"cmd":"pip install pyvips","lang":"bash","label":"Standard installation (requires system libvips)"},{"cmd":"pip install \"pyvips[binary]\"","lang":"bash","label":"Installation with pre-built libvips (may lack features)"}],"dependencies":[{"reason":"Core image processing library (external C library), version 8.2+ required, 8.9+ for full features.","package":"libvips","optional":false},{"reason":"Python FFI binding for libvips.","package":"cffi","optional":false}],"imports":[{"symbol":"Image","correct":"import pyvips\nimage = pyvips.Image.new_from_file(...)"}],"quickstart":{"code":"import pyvips\nimport os\n\n# Assuming 'input.jpg' exists in the current directory\n# For demonstration, let's create a dummy image if not present\nif not os.path.exists('input.jpg'):\n    # In a real scenario, you'd have an actual image file.\n    # For this quickstart, we'll create a simple black image.\n    dummy_image = pyvips.Image.black(100, 100, bands=3)\n    dummy_image.write_to_file('input.jpg')\n\n# Load an image\nimage = pyvips.Image.new_from_file('input.jpg')\n\n# Perform an operation, e.g., resize to 50% and convert to grayscale\nprocessed_image = image.resize(0.5).colourspace('b-w')\n\n# Save the processed image\nprocessed_image.write_to_file('output_grayscale.png')\n\nprint(f\"Processed image saved to output_grayscale.png (width: {processed_image.width}, height: {processed_image.height})\")\n","lang":"python","description":"This example loads an image, resizes it to 50% of its original dimensions, converts it to grayscale, and then saves it as a PNG file. It demonstrates the basic `new_from_file`, chained operations, and `write_to_file` methods. A dummy 'input.jpg' is created if not found for immediate execution."},"warnings":[{"fix":"Install `libvips` system-wide (e.g., `apt install libvips-dev` on Debian/Ubuntu, `brew install vips` on macOS). On Windows, download a pre-compiled binary and add its `bin` directory to your system's `PATH` environment variable, or use `pip install \"pyvips[binary]\"` for a self-contained (but feature-limited) installation.","message":"The `libvips` shared library is a mandatory external dependency. If not installed on your system, `pyvips` will fail to import with an `OSError` or `ModuleNotFoundError` for `_libvips`.","severity":"breaking","affected_versions":"All versions"},{"fix":"For full `libvips` features, install `libvips` separately through your system's package manager or from source, ensuring it includes desired optional dependencies, and then install `pyvips` without the `[binary]` extra (`pip install pyvips`).","message":"Using `pip install \"pyvips[binary]\"` installs a self-contained `libvips` binary that may lack support for certain features like PDF loading, OpenSlide (for whole-slide images), or specific image formats. If you need these, a system-wide installation of `libvips` with full feature support is necessary.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always call `.copy()` on an `Image` object before attempting to modify its metadata if there's a possibility it's being shared, e.g., `new_image = original_image.copy().set('field', value)`.","message":"Since `libvips` version 8.9, modifying metadata on 'shared' images (those with a reference count greater than one) is blocked to prevent race conditions. Attempts to do so will be ignored or raise a warning.","severity":"breaking","affected_versions":"libvips >= 8.9"},{"fix":"For complex drawing tasks, consider combining drawing elements into an overlay image and using `image.composite()` or equivalent methods to merge them efficiently, or perform drawing operations on a temporary image if performance is critical.","message":"Operations that draw directly onto an image, such as `Image.draw_circle()` or `Image.draw_line()`, inherently modify their input. `pyvips` will make a private copy of the image in memory before performing these operations to prevent crashes. Repeated drawing can thus be inefficient due to multiple memory copies.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure you have `libvips` development headers and a working C compiler (e.g., build-essential on Linux, Xcode Command Line Tools on macOS) installed before running `pip install pyvips`. If issues persist, try `pip install --no-cache-dir pyvips` to force a clean build attempt.","message":"If `cffi` is unable to build a binary extension for `pyvips` (API mode), it will fall back to ABI mode, which results in approximately 20% slower execution and longer startup times.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure you are using a 64-bit Python installation and a 64-bit build of `libvips`. Verify `libvips` was compiled with support for large file sizes if you frequently encounter such issues.","message":"When processing extremely large images, errors like 'arithmetic overflow' can occur, often stemming from underlying `libvips` components (e.g., `libpng`) if a 32-bit `libvips` build is in use. This limits the maximum image size that can be handled.","severity":"gotcha","affected_versions":"All versions, particularly with 32-bit `libvips` builds"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}