Duplicate Image Finder avatar

Duplicate Image Finder

Pricing

$0.40 / 1,000 results

Go to Apify Store
Duplicate Image Finder

Duplicate Image Finder

Find duplicate and near-duplicate images in image URLs or an upload by perceptual hash. Use when you need to dedupe an image set or spot resized copies.

Pricing

$0.40 / 1,000 results

Rating

0.0

(0)

Developer

Plain Pipe

Plain Pipe

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

Find duplicate and near-duplicate images among your image links or an upload with perceptual hashes (dHash and aHash): one row per image with its hashes, group and closest match.

Use this when: you have a list of image links and need to know which ones show the same picture, even at a different size or JPEG quality.

Why this one

  • $0.40 per 1,000 results, one result per image; links that fail or are not images are not charged.
  • Each row carries both 64-bit hashes (dHash, aHash), the per-hash Hamming distances, a groupId/groupSize cluster and the closest earlier image, so you can re-threshold without re-running.
  • Pure JavaScript hashing: no browser, no proxy, no external service. The prefilled example (3 images) finishes in under 4 seconds in our test runs.
  • Checked before each release against the prefilled input plus 7 edge-case inputs (redirects, SVG and 404 links, bad thresholds).

What it does

Give it a list of image links (and optionally one uploaded file). It fetches each image, computes two 64-bit perceptual hashes with jimp, a pure JavaScript image library, and compares them. Images that look the same, such as one picture saved at different sizes or re-compressed as JPEG, get the same group ID even when their files differ byte for byte.

The two hashes are computed by the Actor itself:

  • dHash: the image is scaled to 9x8 grayscale and each bit records whether a pixel is darker than its right neighbour.
  • aHash: the image is scaled to 8x8 grayscale and each bit records whether a pixel is brighter than the mean.

Two images match when both hashes differ in at most threshold bits (Hamming distance).

Use cases

  • Clean up a media library: find the same picture stored at several sizes or re-saved as JPEG.
  • Check a product catalog for repeated photos across different items.
  • Flag re-uploads of an image before they go live.
  • Find all copies of one reference image in a list (againstFirst mode).
  • Deduplicate an image set before you use it for testing or training.

How to use it

  1. Paste image links into Image URLs, one per line, or upload a file in Upload an image. You need at least two images.
  2. Under Matching settings, optionally set Threshold (default 6; lower is stricter) and Compare mode.
  3. Run the Actor. Results land in the dataset; export them as JSON, CSV or Excel, or read them through the API.
  4. Sort or filter by groupId to see each cluster of near-duplicates, or filter on isDuplicate: true to list the copies only.

Input

FieldWhat it doesDefaultExample
imageUrlsDirect links to PNG, JPEG, GIF, BMP or TIFF files, one per line (2 to 500). Entries that are not http(s) links fail the run before any image is fetched.none["https://www.w3.org/Graphics/PNG/nurbcup2si.png", "..."]
imageFileOne uploaded image, listed after the URLs.noneupload in the form
thresholdMaximum Hamming distance (0-64 bits) for two images to count as near-duplicates.63
compareModeall-pairs compares each image with every earlier image and groups chains of matches; againstFirst compares each image only with the first one.all-pairs"againstFirst"
maxItemsStop after this many result rows.100500

Output

One row per image that could be fetched and decoded, in input order. Example from a real run (prefill input: the same photo at 250 px and 500 px wide, plus an unrelated PNG); this is the 500 px copy:

{
"source": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Example.jpg/500px-Example.jpg",
"width": 500,
"height": 517,
"format": "jpeg",
"sizeBytes": 20241,
"dHash": "40682c1b0f070101",
"aHash": "ff2f87c3e1f1f9ff",
"groupId": 1,
"groupSize": 2,
"isDuplicate": true,
"duplicateOf": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Example.jpg/250px-Example.jpg",
"distance": 0,
"dHashDistance": 0,
"aHashDistance": 0,
"closestEarlier": "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Example.jpg/250px-Example.jpg"
}
FieldMeaning
dHash, aHash16-character hex strings (64 bits each).
groupId / groupSizeImages in the same cluster of near-duplicates share this number; groups are numbered in order of first appearance. groupSize is how many images the group holds.
closestEarlier / distanceThe earlier image (among those compared) with the smallest distance, and that distance: the larger of dHashDistance and aHashDistance. null for the first image.
duplicateOf / isDuplicateSet to closestEarlier only when distance is within the threshold, otherwise null; isDuplicate says the same as a boolean.

Pricing

Pay per result: $0.40 per 1,000 results ($0.0004 per result). One result is one image row. You only pay for results the Actor returns. Set a maximum total charge on the run to cap your spend.

Limits

  • At most 500 images per run and 20 MB per file. Links must point straight at the image; the file signature must be PNG, JPEG, GIF, BMP or TIFF. WebP, AVIF, HEIC and SVG are not supported.
  • Perceptual hashes catch resized, re-compressed and lightly edited copies. They do not reliably catch crops, rotations, mirrored copies, heavy filters or large overlays, and very simple images (flat colours, plain logos) can match each other by chance. Lower the threshold if you see false matches.
  • Transparent pixels are treated as white. Animated GIFs are compared by their first frame.
  • In all-pairs mode groups are chained: if A matches B and B matches C, all three share a group even when A and C are further apart than the threshold.
  • Files that cannot be fetched or decoded are skipped with a warning and not charged. If fewer than two images can be decoded, the run fails with no results and no charge.

FAQ

How much does it cost? $0.0004 per image row, so 1,000 images cost $0.40. Links that fail or are not images are skipped and not charged.

Which threshold should I use? Start with the default 6. If unrelated images match, lower it (3 or less); if resized copies are missed, raise it a little (8-10). 0 matches identical hashes only.

Why was an image skipped? The run log gives the reason: an HTTP error, a link to a web page instead of the file, an unsupported format (WebP, SVG) or a file above 20 MB.

Does it find byte-for-byte identical files only? No. It compares how the images look, so a resized or re-compressed copy matches too. Identical files always have distance 0.

Can I use it from my own code? Yes. Start the Actor through the Apify API with a JSON input and read the dataset; group by groupId.

This Actor processes only what you give it or public, non-personal technical data. It does not log in anywhere, does not collect personal data, and does not bypass paywalls, CAPTCHAs or access controls. You are responsible for having the right to process the inputs you provide.

Support

Open an issue on the Issues tab. Issues are answered within 14 days.

Built and maintained by Plain Pipe.