Skip to content

Installing

pip install python-libphash

Wheels

Wheels exist for the platforms libphash's own CI builds and tests:

Platform Wheel
Linux x86-64 (glibc 2.28 or later) manylinux_2_28_x86_64
Linux arm64 (glibc 2.28 or later) manylinux_2_28_aarch64
macOS arm64 (11 or later) macosx_11_0_arm64
Windows x86-64 win_amd64

for every CPython from 3.10 on, and for the free-threaded builds from 3.14t on: one abi3 wheel per platform serves every CPython with the GIL, a later release of Python included, and each free-threaded version has a wheel of its own. Each wheel links libphash and its decoders statically (libjpeg-turbo, libpng, libwebp, zlib-ng, stb_image), and needs only the system's C library: no system libpng or libjpeg is used, and the decoders inside cannot clash with another copy of the same libraries in the process, such as Pillow's or OpenCV's.

x86-64 wheels need a CPU with SSE4.2 and POPCNT (x86-64-v2: Intel since 2008, AMD since 2011), the baseline libphash is built for. libjpeg-turbo and libwebp choose faster instructions (AVX2) at run time where the CPU has them.

To see what an installed wheel carries:

import libphash as ph

print(ph.__version__)            # 2.0.2.0
print(ph.libphash_version())     # 2.0.2
print(ph.build_info())           # version=2.0.2 jpeg=libjpeg-turbo png=libpng ...

Each wheel also carries a software bill of materials, python_libphash-*.dist-info/sboms/, naming every library linked into it with its version.

Building from source

On any other platform pip builds the sdist, which needs a C compiler (GCC or Clang; Visual Studio Build Tools on Windows). CMake and Ninja come from PyPI. The sdist carries libphash and its vendored decoders, so the build needs no network once the build requirements are installed.

From a clone:

git clone https://github.com/gudoshnikovn/python-libphash.git
cd python-libphash
git submodule update --init --recursive
pip install .

The build runs libphash's own CMake project with its release settings (static, the full decoder set, -ffp-contract=off, hidden symbols), so a source build hashes like a wheel. On macOS, ARCHFLAGS chooses the architecture (ARCHFLAGS="-arch x86_64"); on Windows, the architecture of the Python running the build does.

Building without the native JPEG decoder is possible, and changes JPEG hashes by a few bits: stb_image decodes JPEG to slightly different pixels than libjpeg-turbo, so its hashes are compared with libjpeg-turbo's by distance, never by equality. LIBPHASH_CMAKE_ARGS="-DPHASH_USE_LIBJPEG_TURBO=OFF" pip install . builds that way, and build_info() then says jpeg=stb_image.

Versions

The version has four numbers, X.Y.Z.N: X.Y.Z is the bundled libphash, N the revision of the binding. Hash values depend on X.Y.Z and the configuration only, so to keep the hashes of a stored collection comparable while still receiving fixes of the binding, pin the first three:

pip install "python-libphash==2.0.2.*"

Versions explains the scheme.