Skip to main content

Overview

This guide helps you migrate from imghash v1 to v2. Version 2 introduces significant improvements in API design, type safety, and extensibility while maintaining the core functionality.
The full migration guide is maintained in the project Wiki. This page provides a quick overview of the main changes.

Quick Migration Checklist

1

Update Import Path

Change your import path to include the /v2 suffix:
// v1
import "github.com/ajdnik/imghash"

// v2
import "github.com/ajdnik/imghash/v2"
2

Update Constructor Calls

Algorithm constructors now return errors and use functional options:
// v1
avg := imghash.NewAverage()

// v2
avg, err := imghash.NewAverage()
if err != nil {
    panic(err)
}
3

Update Hash Method Calls

The Hash method is now called Calculate:
// v1
hash := avg.Hash(img)

// v2
hash, err := avg.Calculate(img)
if err != nil {
    panic(err)
}
4

Update Distance Calculations

Distance metrics are now in the similarity package:
// v1
dist := imghash.HammingDistance(h1, h2)

// v2
import "github.com/ajdnik/imghash/v2/similarity"

dist, err := similarity.Hamming(h1, h2)
if err != nil {
    panic(err)
}

Major Changes

Package Structure

import "github.com/ajdnik/imghash"

// Everything in one package
avg := imghash.NewAverage()
hash := avg.Hash(img)
dist := imghash.HammingDistance(h1, h2)

Error Handling

V2 introduces comprehensive error handling throughout the API:
// Constructors never failed
avg := imghash.NewAverage()

// Methods could panic or return invalid results
hash := avg.Hash(img)

// No validation
dist := imghash.HammingDistance(h1, h2)

Configuration Options

V2 uses functional options for cleaner, more extensible configuration:
// Limited customization with struct fields
avg := imghash.NewAverage()
avg.Size = 16
avg.Interpolation = imghash.Bicubic

Hash Types

V2 introduces type-safe hash types:
// Generic []byte or []float64
type Hash interface{}

hash := avg.Hash(img) // Returns interface{}
binaryHash := hash.([]byte)

Distance Metrics

Distance functions moved to dedicated package with validation:
import "github.com/ajdnik/imghash"

dist := imghash.HammingDistance(h1, h2)
dist2 := imghash.EuclideanDistance(h1, h2)

Algorithm-Specific Changes

PDQ

pdq := imghash.NewPDQ()
hash := pdq.Hash(img)
dist := imghash.HammingDistance(h1, h2)

PHash

phash := imghash.NewPHash()
phash.Size = 32
hash := phash.Hash(img)

ColorMoment

cm := imghash.NewColorMoment()
hash := cm.Hash(img)
dist := imghash.EuclideanDistance(h1, h2)

Common Migration Patterns

Pattern 1: Basic Duplicate Detection

import "github.com/ajdnik/imghash"

func isDuplicate(img1, img2 string) bool {
    avg := imghash.NewAverage()
    
    h1 := avg.HashFile(img1)
    h2 := avg.HashFile(img2)
    
    dist := imghash.HammingDistance(h1, h2)
    return dist < 5
}

Pattern 2: Custom Configuration

import "github.com/ajdnik/imghash"

func createCustomHasher() *imghash.MarrHildreth {
    mh := imghash.NewMarrHildreth()
    mh.Scale = 1
    mh.Alpha = 2
    mh.Size = 512
    return mh
}
import "github.com/ajdnik/imghash"

func findSimilar(query string, database []string) []string {
    gist := imghash.NewGIST()
    queryHash := gist.HashFile(query)
    
    var results []string
    for _, img := range database {
        hash := gist.HashFile(img)
        dist := imghash.CosineDistance(queryHash, hash)
        if dist < 0.3 {
            results = append(results, img)
        }
    }
    return results
}

Breaking Changes Summary

These changes require code updates when migrating from v1 to v2:
  1. Import path: Add /v2 suffix
  2. Constructors: Now return (Algorithm, error) instead of just Algorithm
  3. Hash method: Renamed from Hash() to Calculate() and returns error
  4. Distance functions: Moved to similarity package and return errors
  5. Configuration: Use functional options instead of struct fields
  6. Hash types: Strong typing with Binary, UInt8, Float64 types
  7. Compare method: Each algorithm has a Compare() method with default metric

Benefits of V2

Type Safety

Strong typing prevents runtime errors and provides better IDE support

Error Handling

Comprehensive error handling for production reliability

Extensibility

Functional options make it easy to add new configuration

API Clarity

Cleaner separation of concerns with dedicated packages

Getting Help

Full Wiki Guide

Complete migration documentation

Examples

See v2 examples in action

Automated Migration

For large codebases, consider these steps:
  1. Update imports:
    find . -name '*.go' -exec sed -i 's|github.com/ajdnik/imghash"|github.com/ajdnik/imghash/v2"|g' {} +
    
  2. Run tests to identify breaking changes
  3. Fix errors systematically by category (constructors, methods, etc.)
  4. Add error handling where needed
  5. Validate with comprehensive test coverage
Start with a small subset of your codebase to validate the migration approach before applying it broadly.

Build docs developers (and LLMs) love