PHPackages                             jedisct1/libpuzzle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Image &amp; Media](/categories/media)
4. /
5. jedisct1/libpuzzle

AbandonedArchivedLibrary[Image &amp; Media](/categories/media)

jedisct1/libpuzzle
==================

A library to quickly find visually similar images.

2675.6k68[8 issues](https://github.com/jedisct1/libpuzzle/issues)[1 PRs](https://github.com/jedisct1/libpuzzle/pulls)C

Since Aug 11Pushed 8y ago29 watchersCompare

[ Source](https://github.com/jedisct1/libpuzzle)[ Packagist](https://packagist.org/packages/jedisct1/libpuzzle)[ RSS](/packages/jedisct1-libpuzzle/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

```

                               .:. LIBPUZZLE .:.

                         http://libpuzzle.pureftpd.org

            ------------------------ BLURB ------------------------

The Puzzle library is designed to quickly find visually similar images (gif,
png, jpg), even if they have been resized, recompressed, recolored or slightly
modified.

The library is free, lightweight yet very fast, configurable, easy to use and
it has been designed with security in mind. This is a C library, but it also
comes with a command-line tool and PHP bindings.

          ------------------------ REFERENCE ------------------------

The Puzzle library is a implementation of "An image signature for any kind of
image", by H. CHI WONG, Marschall BERN and David GOLDBERG.

         ------------------------ COMPILATION ------------------------

In order to load images, the library relies on the GD2 library.
You need to install gdlib2 and its development headers before compiling
libpuzzle.
The GD2 library is available as a pre-built package for most operating systems.
Debian and Ubuntu users should install the "libgd2-dev" or the "libgd2-xpm-dev"
package.
Gentoo users should install "media-libs/gd".
OpenBSD, NetBSD and DragonflyBSD users should install the "gd" package.
MacPorts users should install the "gd2" package.
X11 support is not required for the Puzzle library.

Once GD2 has been installed, configure the Puzzle library as usual:

./configure

This is a standard autoconf script, if you're not familiar with it, please
have a look at the INSTALL file.

Compile the beast:

make

Try the built-in tests:

make check

If everything looks fine, install the software:

make install

If anything goes wrong, please submit a bug report to:
                       libpuzzle [at] pureftpd [dot] org

            ------------------------ USAGE ------------------------

The API is documented in the libpuzzle(3) and puzzle_set(3) man pages.
You can also play with the puzzle-diff test application.
See puzzle-diff(8) for more info about the puzzle-diff application.

In order to be thread-safe, every exported function of the library requires a
PuzzleContext object. That object stores various run-time tunables.

Out of a bitmap picture, the Puzzle library can fill a PuzzleCVec object :

  PuzzleContext context;
  PuzzleCVec cvec;

  puzzle_init_context(&context);
  puzzle_init_cvec(&context, &cvec);
  puzzle_fill_cvec_from_file(&context, &cvec, "directory/filename.jpg");

The PuzzleCvec structure holds two fields:
  signed char *vec:  a pointer to the first element of the vector
  size_t sizeof_vec: the number of elements

The size depends on the "lambdas" value (see puzzle_set(3)).

PuzzleCvec structures can be compared:

  d = puzzle_vector_normalized_distance(&context, &cvec1, &cvec2, 1);

d is the normalized distance between both vectors. If d is below 0.6, pictures
are probably similar.

If you need further help, feel free to subscribe to the mailing-list (see
below).

          ------------------------ INDEXING ------------------------

How to quickly find similar pictures, if they are millions of records?

The original paper has a simple, yet efficient answer.

Cut the vector in fixed-length words. For instance, let's consider the
following vector:

[ a b c d e f g h i j k l m n o p q r s t u v w x y z ]

With a word length (K) of 10, you can get the following words:

[ a b c d e f g h i j ] found at position 0
[ b c d e f g h i j k ] found at position 1
[ c d e f g h i j k l ] found at position 2
etc. until position N-1

Then, index your vector with a compound index of (word + position).

Even with millions of images, K = 10 and N = 100 should be enough to have very
little entries sharing the same index.

Here's a very basic sample database schema:

+-----------------------------+
|          signatures         |
+-----------------------------+
| sig_id | signature | pic_id |
+--------+-----------+--------+

+--------------------------+
|           words          |
+--------------------------+
| pos_and_word | fk_sig_id |
+--------------+-----------+

I'd recommend splitting at least the "words" table into multiple tables and/or
servers.

By default (lambas=9) signatures are 544 bytes long. In order to save storage
space, they can be compressed to 1/third of their original size through the
puzzle_compress_cvec() function. Before use, they must be uncompressed with
puzzle_uncompress_cvec().

         ------------------------ PUZZLE-DIFF ------------------------

A command-line tool is also available for scripting or testing.

It is installed as "puzzle-diff" and comes with a man page.

Sample usage:

- Output distance between two images:

$ puzzle-diff pic-a-0.jpg pics-a-1.jpg
0.102286

- Compare two images, exit with 10 if they look the same, exit with 20 if
they don't (may be useful for scripts):

$ puzzle-diff -e pic-a-0.jpg pics-a-1.jpg
$ echo $?
10

- Compute distance, without cropping and with computing the average intensity
of the whole blocks:

$ puzzle-diff -p 1.0 -c pic-a-0.jpg pic-a-1.jpg
0.0523151

  ------------------------ COMPARING IMAGES WITH PHP ------------------------

A PHP extension is bundled with the Libpuzzle package, and it provides PHP
bindings to most functions of the library.

Documentation for the Libpuzzle PHP extension is available in the README-PHP
file.

    ------------------------ APPS USING LIBPUZZLE ------------------------

Here are third-party projects using libpuzzle:

* ftwin - http://jok.is-a-geek.net/ftwin.php
  ftwin is a tool useful to find duplicate files according to their content on
your file system.

* Python bindings for libpuzzle: PyPuzzle
  https://github.com/ArchangelSDY/PyPuzzle

           ------------------------ STATUS ------------------------

This project is unfortunately not maintained any more. Pull requests are
always welcome, but I don't use this library any more and I don't have enough
spare time to actively work on it.
```

###  Health Score

32

—

LowBetter than 71% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity39

Limited adoption so far

Community24

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 75.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/1e48d21350d7b97bc429d1e848ca8d710ec5ff31298f1dc408c0ab985ed4a5e0?d=identicon)[jedisct1](/maintainers/jedisct1)

---

Top Contributors

[![jedisct1](https://avatars.githubusercontent.com/u/124872?v=4)](https://github.com/jedisct1 "jedisct1 (22 commits)")[![Benny-](https://avatars.githubusercontent.com/u/516316?v=4)](https://github.com/Benny- "Benny- (3 commits)")[![fujidig](https://avatars.githubusercontent.com/u/823043?v=4)](https://github.com/fujidig "fujidig (2 commits)")[![ArchangelSDY](https://avatars.githubusercontent.com/u/858914?v=4)](https://github.com/ArchangelSDY "ArchangelSDY (1 commits)")[![waldyrious](https://avatars.githubusercontent.com/u/478237?v=4)](https://github.com/waldyrious "waldyrious (1 commits)")

### Embed Badge

![Health badge](/badges/jedisct1-libpuzzle/health.svg)

```
[![Health](https://phpackages.com/badges/jedisct1-libpuzzle/health.svg)](https://phpackages.com/packages/jedisct1-libpuzzle)
```

###  Alternatives

[milon/barcode

Barcode generator like Qr Code, PDF417, C39, C39+, C39E, C39E+, C93, S25, S25+, I25, I25+, C128, C128A, C128B, C128C, 2-Digits UPC-Based Extention, 5-Digits UPC-Based Extention, EAN 8, EAN 13, UPC-A, UPC-E, MSI (Variation of Plessey code)

1.5k13.3M39](/packages/milon-barcode)[bkwld/croppa

Image thumbnail creation through specially formatted URLs for Laravel

510496.0k22](/packages/bkwld-croppa)[char0n/ffmpeg-php

PHP wrapper for FFmpeg application

495225.1k1](/packages/char0n-ffmpeg-php)[goat1000/svggraph

Generates SVG graphs

132849.6k3](/packages/goat1000-svggraph)[cohensive/embed

Media Embed (for Laravel or as a standalone).

120370.4k](/packages/cohensive-embed)[netresearch/rte-ckeditor-image

Image support in CKEditor for the TYPO3 ecosystem - by Netresearch

63991.3k4](/packages/netresearch-rte-ckeditor-image)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
