{"id":9265,"library":"pyturbojpeg","title":"PyTurboJPEG: High-performance JPEG Handling","description":"PyTurboJPEG is a Python wrapper for the high-performance libjpeg-turbo library, enabling fast decoding and encoding of JPEG images. It leverages the underlying C library for significant speed improvements over pure Python or slower image processing libraries. The library is actively maintained with regular releases, often reflecting updates and features from the upstream libjpeg-turbo project. Current version is 2.2.0.","status":"active","version":"2.2.0","language":"en","source_language":"en","source_url":"https://github.com/lilohuang/PyTurboJPEG","tags":["image-processing","jpeg","libjpeg-turbo","performance","computer-vision"],"install":[{"cmd":"pip install pyturbojpeg","lang":"bash","label":"Install PyTurboJPEG"}],"dependencies":[],"imports":[{"note":"The primary class for all JPEG operations.","symbol":"TurboJPEG","correct":"from pyturbojpeg import TurboJPEG"}],"quickstart":{"code":"from pyturbojpeg import TurboJPEG, TJPF_BGR, TJ_BGR\nimport numpy as np\nimport os\n\n# Instantiate TurboJPEG. Optionally, pass the path to libturbojpeg.so.0, .dylib, or .dll\n# Example: jpeg = TurboJPEG('/usr/local/lib/libturbojpeg.so.0')\njpeg = TurboJPEG()\n\n# --- Encode Example ---\n# Create a dummy BGR image (e.g., from OpenCV or Pillow in BGR mode)\nwidth, height = 640, 480\n# For simplicity, create a blank image; in real use, this would be actual image data\n# PyTurboJPEG expects contiguous C-style arrays for input\ndummy_img_array = np.zeros((height, width, 3), dtype=np.uint8)\n# Set a pixel to demonstrate it's not entirely blank, just to ensure data is there\ndummy_img_array[50, 50] = [255, 0, 0] # Blue pixel\n\n# Encode the NumPy array (its byte representation) to JPEG\n# TJPF_BGR indicates the input pixel format\ntry:\n    jpeg_data = jpeg.encode(dummy_img_array.tobytes(), width, height, TJPF_BGR, quality=85)\n    print(f\"Successfully encoded JPEG data. Size: {len(jpeg_data)} bytes\")\n\n    # Save to a file for verification (optional)\n    # with open('output.jpg', 'wb') as f:\n    #     f.write(jpeg_data)\n\n    # --- Decode Example ---\n    # Decode the JPEG data back to raw pixel data\n    # TJ_BGR indicates the desired output colorspace (constant for BGR output)\n    decoded_image_data, decoded_width, decoded_height, decoded_pix_fmt, decoded_colorspace = \\\n        jpeg.decode(jpeg_data, TJ_BGR)\n\n    print(f\"Decoded image: {decoded_width}x{decoded_height}, \"\n          f\"Pixel Format: {decoded_pix_fmt}, Colorspace: {decoded_colorspace}\")\n\n    # Convert decoded raw data back to a NumPy array\n    decoded_array = np.frombuffer(decoded_image_data, dtype=np.uint8).reshape((decoded_height, decoded_width, 3))\n    print(f\"Decoded NumPy array shape: {decoded_array.shape}\")\n\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\n    print(\"Please ensure libjpeg-turbo is correctly installed and discoverable by PyTurboJPEG.\")\n    print(\"You might need to set LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (macOS), or PATH (Windows).\")\n    print(\"Alternatively, explicitly pass the library path to TurboJPEG() constructor.\")\n\n","lang":"python","description":"This quickstart demonstrates how to initialize PyTurboJPEG, create a dummy image (using NumPy), encode it into JPEG format, and then decode the JPEG data back into a raw pixel buffer, converting it back to a NumPy array for further processing. It includes error handling guidance for common issues related to the libjpeg-turbo dependency."},"warnings":[{"fix":"Review your `encode()` and `decode()` calls against the latest PyTurboJPEG documentation. Pay attention to changes in parameter names, expected types, or available flags. If encountering `TypeError` or `ValueError`, consult the source code or latest README for argument signatures.","message":"Version 2.0.0 migrated to the TurboJPEG 3.1.x function-based API. While the Python `TurboJPEG` class structure remains similar, underlying C API changes might lead to `TypeError` or `ValueError` if specific (especially low-level or less common) parameters or flag combinations from pre-2.0.0 versions are used.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Install `libjpeg-turbo` via your system's package manager (e.g., `sudo apt-get install libturbojpeg0` on Debian/Ubuntu, `brew install libjpeg-turbo` on macOS) or download binaries. Ensure the library's path is discoverable by your system's dynamic linker (e.g., set `LD_LIBRARY_PATH` on Linux, `DYLD_LIBRARY_PATH` on macOS, or `PATH` on Windows) or explicitly pass the full path to the `TurboJPEG()` constructor: `jpeg = TurboJPEG('/path/to/libturbojpeg.so')`.","message":"PyTurboJPEG is a wrapper library and requires the native `libjpeg-turbo` shared library (e.g., `libturbojpeg.so.0` on Linux, `libturbojpeg.dylib` on macOS, `turbojpeg.dll` on Windows) to be installed on your system. Without it, PyTurboJPEG cannot function and will raise an `OSError`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure your NumPy arrays are C-contiguous before passing them to `encode()` or `decode()`. Use `.copy(order='C')` if necessary, e.g., `img_array.copy(order='C').tobytes()`. Version 1.7.5 introduced internal checks to ensure contiguous arrays.","message":"PyTurboJPEG's performance benefits are maximized with `numpy` arrays, but it expects input buffers (e.g., from `numpy.ndarray.tobytes()`) to be C-contiguous. If you pass a non-contiguous array, it may result in incorrect output or errors.","severity":"gotcha","affected_versions":"<1.7.5 (potential issues), All versions (best practice)"},{"fix":"Be aware of new constants and parameters related to precision (e.g., `TJ_PRECISION_12`, `TJ_PRECISION_16`) and lossless options. Consult the documentation for specific API calls if working with non-8-bit or lossless JPEGs.","message":"Versions 2.1.0 and newer introduce support for 12-bit and 16-bit precision JPEGs, as well as lossless JPEG. If your application previously only handled 8-bit standard JPEGs, ensure your decoding and encoding pipelines explicitly manage precision settings if you encounter these new formats, to avoid unexpected truncation or errors.","severity":"gotcha","affected_versions":">=2.1.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Install `libjpeg-turbo` using your system's package manager (e.g., `sudo apt-get install libturbojpeg0` on Linux, `brew install libjpeg-turbo` on macOS) or download and place the library file (e.g., `libturbojpeg.so.0`) in a directory listed in your system's dynamic linker search paths (`LD_LIBRARY_PATH`, `DYLD_LIBRARY_PATH`, `PATH`). Alternatively, initialize `TurboJPEG` with the explicit path: `jpeg = TurboJPEG('/usr/local/lib/libturbojpeg.so.0')`.","cause":"The `libjpeg-turbo` shared library is not installed or not found in standard system library paths.","error":"OSError: cannot open shared object file: libturbojpeg.so.0: No such file or directory"},{"fix":"Check the official PyTurboJPEG GitHub README or source code for the correct `encode()`/`decode()` method signatures for your installed version. Adjust your keyword arguments accordingly.","cause":"You are using an argument name or a parameter that was removed or renamed in a newer version of PyTurboJPEG (most likely after v2.0.0 API migration).","error":"TypeError: encode() got an unexpected keyword argument 'old_param'"},{"fix":"Before passing a NumPy array's bytes to `encode()` or `decode()`, ensure it is C-contiguous by calling `.copy(order='C')` on the array: `jpeg.encode(my_array.copy(order='C').tobytes(), ...)`.","cause":"The input NumPy array's byte representation (obtained via `.tobytes()`) is not C-contiguous, which is required by `libjpeg-turbo` for direct memory access.","error":"ValueError: Input array is not C-contiguous"}]}