saade/facehash
Generate and compare perceptual “face hashes” to identify similar faces across images. Lightweight Laravel-friendly package with simple APIs for hashing, distance checks, and quick matching—useful for deduplication, grouping, and basic face similarity search.
Installation
composer require saade/facehash
No additional configuration is required—just autoload.
First Use Case Generate a deterministic avatar hash from a string (e.g., user email or name):
use Saade\Facehash\Facades\Facehash;
$hash = Facehash::generate('john.doe@example.com');
// Returns: "0123456789abcdef" (32-character hex string)
Where to Look First
User Avatar Generation
// In a User model or service
public function avatarHash(): string
{
return Facehash::generate($this->email);
}
<img src="https://api.facehash.com/{{ $user->avatarHash() }}" alt="Avatar">
Caching Deterministic Outputs Since hashes are deterministic, cache them to avoid recomputation:
$hash = Cache::remember("facehash_{$user->email}", now()->addYear(), function () use ($user) {
return Facehash::generate($user->email);
});
Integration with Storage Store hashes in the database alongside user records:
// Migration
Schema::create('users', function (Blueprint $table) {
$table->string('facehash')->unique();
});
Dynamic Avatar URLs Use the hash to generate consistent URLs (e.g., Gravatar-style):
route('avatar.show', ['hash' => $user->facehash]);
Route::get('/avatar/{hash}', [AvatarController::class, 'show'])
->name('avatar.show');
Batch Processing Generate hashes for existing users:
User::chunk(100, function ($users) {
foreach ($users as $user) {
$user->update(['facehash' => Facehash::generate($user->email)]);
}
});
Case Sensitivity
Facehash::generate('John') ≠ Facehash::generate('john'). Normalize input:
Facehash::generate(strtolower($input));
Unicode/Non-ASCII Input The library handles Unicode, but performance may vary. Test with:
Facehash::generate('José'); // Works, but benchmark if processing millions.
Collision Risk While collisions are statistically rare, avoid using hashes as primary keys or sensitive identifiers.
Database Indexing If storing hashes in a database, ensure the column is indexed for lookups:
$table->string('facehash')->unique()->index();
Verify Outputs Cross-check hashes with the JavaScript reference for consistency:
// Node.js
const facehash = require('facehash');
console.log(facehash('test')); // Compare with PHP output
Performance Bottlenecks For bulk operations, profile with:
$start = microtime(true);
Facehash::generate('long_string_repeated_1000_times');
echo microtime(true) - $start; // ~0.001s per hash (varies by input)
Custom Hash Algorithms Extend the core class to modify the hashing logic:
class CustomFacehash extends \Saade\Facehash\Facehash {
protected function hashAlgorithm(): string {
return 'sha256'; // Override default
}
}
Avatar Themes Combine with other packages (e.g., laravel-avatar) for themed avatars:
use LaravelAvatar\Facades\LaravelAvatar;
$avatar = LaravelAvatar::create($user->email)
->setSize(100)
->setFormat('png')
->setBackgroundColor('#f0f0f0')
->setFontColor('#333')
->setFontFamily('Arial')
->setFontSize(50)
->setText($user->facehash()->substring(0, 2));
WebP Support If serving avatars via Laravel, ensure your storage driver supports WebP:
// In config/filesystems.php
'disks' => [
'avatars' => [
'driver' => 's3',
'url' => env('AWS_URL'),
'visibility' => 'public',
'thumb_options' => [
'mode' => 'crop',
'extension' => 'webp',
],
],
];
Fallback for Missing Inputs
Handle null or empty strings gracefully:
$hash = Facehash::generate($user->email ?? 'default@example.com');
Facehash class.How can I help you explore Laravel packages today?