PHPackages                             aodto/phasher - 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. aodto/phasher

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

aodto/phasher
=============

Image Processing Library for comparing images

018.1k↓50%5PHP

Since Jan 15Pushed 11y ago1 watchersCompare

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

READMEChangelog (1)DependenciesVersions (2)Used By (5)

Perceptual hashing is a method to generate a hash of an image which allows multiple images to be compared by an index of similarity. You can find out more at [The Hacker Factor](http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html) and [phash.org](http://phash.org).

I've extended this basic method into a class which can also compare images which have been rotated or flipped (but only in 90 degree increments.) It can also match images which have been color corrected (to a degree) or altered. This flexibility, though, does lend itself to false positives and it's ridiculously slow - currently it takes about a second to hash and compare images -- in production you would want to generate a cache of hashes for existing images, perhaps, and then compare the hash of an image to the hashes.

PHasher is available under the MIT license.

---

\###Usage###

```
include_once('phasher.class.php');
$I = PHasher::Instance();

```

*yes. it's a singleton.*

```
$I->HashImage($res, $rot=0, $mir=0, $size=8);

```

build a perceptual hash out of an image.

- **$res** is an image filename.
- **$rot** create the hash as if the image were rotated by this value. Default is 0, allowed values are 90, 180, 270.
- **$mir** create the hash as though the image were mirrored and/or flipped. Default value is 0, 1 is mirrored, 2 is flipped, 3 is both mirrored and flipped.

*this is currently still buggy.*

- **$size** the size of the thumbnail created from the original image - the hash will be the square of this (so a value of 8 will build a hash out of an 8x8 image, of 64 bits.)

This returns an array of binary values representing the perceptual hash. This is done as an array to make it easier to process.

```
$I->Compare($res1, $res2, $rot=0, $precision=1);

```

build perceptual hashes out of two images, compare them and return the similarity between them as a percentage.

- **$res1** is an image filename.
- **$res2** is another image filename.
- **$rot** create the hash as if the second image were rotated by this value. Default is 0, allowed values are 90, 180, 270.
- **$precision** return to this many decimal places. Default is 1.

```
$I->Detect($res1, $res2, $precision=1);

```

Compare two images through all rotations and return the highest match value.

```
$I->FastHashImage($res, $size=8);

```

Faster hashing method without any rotation. Returns the same array as HashImage.

```
$I->HashAsString($hash, $hex=true);

```

convert a hash array returned by one of the HashImage methods into a string of hex (if $hex == true) or binary (if $hex==false.)

```
$I->HashAsTable($hash, $size=8, $cellsize=10);

```

convert a hash array into an html table, with each cell being either white or black depending on its value. this is only being used for demos and debugging and should be avoided as being mostly useless and slow.

### example usage

[](#example-usage)

find a percentage of similarity between 'image1.jpg' and 'image2.jpg.'. Compare at 90 degree angles.

```
$I = PHasher::Instance();
$file1 = 'image1.jpg';
$file2 = 'image2.jpg';
$result = $I->Compare($file1, $file2);
$result90 = $I->Compare($file1, $file2, 90);
$result180 = $I->Compare($file1, $file2, 180);
$result270 = $I->Compare($file1, $file2, 270);
$max_match = max($result, $result90, $result180, $result270);

```

the above is the same as:

```
$I = PHasher::Instance();
$file1 = 'image1.jpg';
$file2 = 'image2.jpg';
$result = $I->Detect($file1, $file2);

```

### notes

[](#notes)

Sebastian Lasse of the Redaktor Project has built an [implementation of phasher in javascript](https://redaktorcms.com/dev/phasher/demo_js/index.html), using the dojo library, which is pretty cool.

I'm still trying to speed the algorithm up and improve the hashing, since it does on occasion produce false positives (it was originally meant to catch imagespam on forums and imageboards so it's as aggressive as it can be.) If anyone wants to add discrete cosine transform to this by all means make a pull request because I still don't know how to do it.

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity24

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 89.7% 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/8c45140a4fbd44d6f39f793224cae1072ed65a85fb60909d06b6ffcb468fba44?d=identicon)[aodto](/maintainers/aodto)

---

Top Contributors

[![kennethrapp](https://avatars.githubusercontent.com/u/665097?v=4)](https://github.com/kennethrapp "kennethrapp (26 commits)")[![aodto](https://avatars.githubusercontent.com/u/626168?v=4)](https://github.com/aodto "aodto (1 commits)")[![ImageSearch](https://avatars.githubusercontent.com/u/6505564?v=4)](https://github.com/ImageSearch "ImageSearch (1 commits)")[![Legendante](https://avatars.githubusercontent.com/u/8066984?v=4)](https://github.com/Legendante "Legendante (1 commits)")

### Embed Badge

![Health badge](/badges/aodto-phasher/health.svg)

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

###  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.0k23](/packages/bkwld-croppa)[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)[humanmade/tachyon-plugin

Rewrites WordPress image URLs to use Tachyon

87338.5k2](/packages/humanmade-tachyon-plugin)

PHPackages © 2026

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