Find Duplicate Images & Videos

Select a folder to scan. Supports images (JPG, PNG, GIF, WebP) and videos (MP4, WebM, MOV).

Ready
0 items

📐 How dHash Duplicate Detection Works — Complete Guide

Everything you need to know about finding and cleaning up duplicate files with the dHash (Difference Hash) algorithm. Scroll down for step‑by‑step instructions, tips, and answers to common questions.

100% Private — Your Files Never Leave Your Computer Everything runs inside your browser. No uploads, no accounts, no tracking. Close the tab and all data is gone.

🔍 What This Tool Does

Sakarto looks inside your images and videos to detect duplicates — not just files with the same name. dHash captures the edge and gradient structure of each file rather than its absolute brightness. For each row of pixels in a small grid, it asks: “is this pixel brighter or darker than the one to its right?” The resulting binary pattern encodes how light transitions across the image — its edges, contrasts, and shapes — rather than how bright it is overall.

Gradient‑Based

Captures edge and brightness‑transition structure. Robust to exposure changes, contrast tweaks, and color grading that fool average‑based algorithms.

Very Fast

One comparison per adjacent pixel pair. Among the fastest algorithms in Sakarto — ideal for large folders.

Web Worker Processing

All image hashing runs in a background Web Worker via OffscreenCanvas, keeping the browser tab fully responsive during scanning.

Fast Mode for JPEG

Reads the embedded EXIF thumbnail instead of the full image — 5–10× faster with near‑identical accuracy for most photos.

🧠 How the dHash Algorithm Works

Difference Hash is built on a simple insight: rather than recording how bright each pixel is, record which direction brightness is changing. Here's the full pipeline:

  1. Resize to 17×16 Pixels

    Each image is drawn onto a canvas that is one pixel wider than it is tall — specifically 17×16 for a 256‑bit hash. The extra column is what makes the horizontal gradient comparison possible: every pixel in the 16×16 region has one neighbour to its right. In Fast Mode, JPEG files use their embedded EXIF thumbnail for this step.

  2. Convert Each Pixel to Grayscale

    Each of the 17×16 = 272 pixels is converted to a grayscale value using the luminance formula 0.299×R + 0.587×G + 0.114×B. Color information is discarded at this point — only brightness matters for the gradient comparison.

  3. Compare Each Pixel to Its Right Neighbour

    For each of the 16 rows, and for each of the 16 columns (stopping before the last), the grayscale value of a pixel is compared to the grayscale value of the pixel directly to its right. If the left pixel is brighter than its right neighbour, the bit is 1. If it is equal or darker, the bit is 0.

  4. Produce the 256‑Bit Gradient Hash

    Reading across all 16 rows, each with 16 comparisons, produces a 256‑bit binary fingerprint. This hash encodes the direction of brightness change at 256 positions across the image — a compact map of the image's edge and gradient structure. Two images with the same structural edges and transitions will produce near‑identical hashes regardless of their overall brightness level.

  5. Compare Using Hamming Distance

    To compare two files, their 256‑bit hashes are XOR’d bit by bit. The number of positions where the bits differ is the Hamming distance. A distance of 0 means identical gradient patterns. The similarity threshold slider controls the maximum Hamming distance allowed for two files to be grouped as duplicates. Lower = stricter.

  6. Aspect Ratio Pre‑Check

    Before any hash comparison, Sakarto checks whether the two files have similar aspect ratios. Pairs where proportions differ by more than 10% are skipped entirely, preventing a tall portrait from being matched with a wide landscape even if their gradient patterns coincidentally align.

  7. Videos — Multi‑Frame Averaging

    For video files, 3 frames are extracted at 1.5‑second intervals. Each frame produces its own 256‑bit dHash. The 3 hashes are combined by majority vote per bit to produce a single representative hash for the whole file. Video scanning pauses if you switch browser tabs and resumes when you return.

Why does dHash handle brightness changes so well? Imagine brightening an image by 20%. Every absolute pixel value changes, so an algorithm that compares pixel values to a fixed average (like aHash) may produce a different hash. But the relationship between adjacent pixels — which is brighter? — is unchanged. dHash records these relationships, so a brighter or darker version of the same image produces an identical or near‑identical hash.

🎚️ Understanding the Hamming Threshold Slider

The Similarity Threshold slider (0–50) controls how many bits two hashes can differ and still be grouped as duplicates. It is the most important control on this page.

Low values (0–5) — Very strict

Only nearly identical files match. Use for finding exact copies, different‑bitrate exports of the same master, or lossless vs. lossy conversions. Very few false positives. May miss files where re‑encoding shifted a few edge gradients.

Medium values (6–20) — Balanced (default: 10)

Catches resized copies, re‑compressed files, minor brightness and contrast adjustments, and color‑graded versions. The default of 10 is a good starting point for most photo libraries. dHash is particularly good here because brightness shifts don't change the gradient direction for most pixels.

High values (21–50) — Loose

Groups images with broadly similar edge structures. Useful for finding visually related images that share compositional patterns. Expect more false positives — two different photos shot in similar environments may match. Always review groups before deleting at these values.

Re‑clustering is instant. When you release the slider, all already‑scanned hashes are re‑grouped using the new threshold in a background Web Worker — no re‑scanning needed. The scan only runs once per folder.
Lower = stricter. The slider measures the maximum number of differing hash bits allowed. A value of 0 means “accept only identical gradient patterns.” A value of 10 means “accept up to 10 bit differences out of 256.”

✅ What It Finds — and What It Might Miss

✅ Finds Well
  • Exact byte‑for‑byte copies
  • The same photo at different resolutions
  • Re‑saved copies in different formats (JPEG → PNG → WebP)
  • Brightness‑adjusted or exposure‑corrected versions
  • Contrast‑tweaked or lightly color‑graded copies
  • Re‑compressed JPEG versions
  • Screenshots of the same image
  • Videos with similar structural content across key frames
⚠️ May Struggle With
  • Heavily cropped versions (edges shift position in the grid)
  • Rotated or mirrored images (gradient directions are reversed or transposed)
  • Images with large watermarks or text overlaid
  • Very similar scenes shot moments apart (nearly the same gradients)
  • Black‑and‑white vs. color (grayscale conversion may change local gradients)
  • Heavily posterized or filtered images that eliminate fine gradients
For rotated or perspective‑warped copies, try ORB Feature Matching. For heavily cropped versions, pHash or ORB are more reliable. For noise‑heavy scans or badly compressed files, BlockHash handles artifacts better. dHash shines for brightness and color variations — the scenario where aHash typically fails.

📋 Step‑by‑Step: How to Use Sakarto dHash

Step 1

Select a Folder to Scan

Click 📁 Select Folder to Scan to open a native folder picker (Chrome / Edge). Or drag and drop a folder onto the page. In Firefox or Safari, use the file input fallback.

Enable Fast Mode for JPEG‑heavy libraries. It reads the embedded EXIF thumbnail instead of the full image — 5–10× faster, with the same duplicate detection accuracy in almost all cases.
Step 2

Wait for the Scan

A progress bar shows how many files have been processed. dHash is one of the fastest algorithms in Sakarto. Duplicate groups appear live as they're found — you can start reviewing before the scan finishes.

Step 3

Adjust the Similarity Threshold

After the scan, use the Similarity Threshold slider to tune matching sensitivity. Releasing the slider re‑clusters all results instantly in a background Worker — no re‑scan needed. Start at the default of 10. If you're specifically looking for brightness‑ or color‑adjusted copies, dHash may catch them even at strict thresholds where other algorithms miss them.

Step 4

Review the Duplicate Groups

Results are shown in numbered groups. Each group contains files that look similar to each other.

  • Click a card to select it (blue border)
  • Ctrl+Click (or Cmd+Click on Mac) to add to the compare list (purple border)
  • Click the 🔍 icon on hover to preview full size
  • Right‑click any card for the context menu
  • Click & drag on empty space to box‑select multiple cards
Step 5

Compare Side‑by‑Side

Ctrl+Click two or more cards, then click ⚖️ Compare in the toolbar. A modal opens with full metadata (dimensions, size, type, path) and a similarity percentage. For 3+ files, a pairwise similarity matrix is shown. This is especially useful for dHash results where two images may be the same scene at different exposures — compare to confirm before deleting.

Step 6

Take Action — Move, Delete, or Copy

Select files and use the toolbar buttons. With Queue Mode on (recommended), files are staged for review first:

📋 CopyCopy filename(s) to clipboard
📂 MoveStage for move to a named folder
🗑️ DeleteStage for permanent deletion
⚖️ CompareView selected files side‑by‑side
Step 7

Queue Mode — Review Before You Commit

When Queue Mode is enabled (the default), clicking Move or Delete stages files in a queue instead of acting immediately. Switch to the Move Queue or Delete Queue tab in the sidebar to review what's staged, remove individual files, then execute when ready.

With Queue Mode disabled, a confirmation dialog appears and the operation runs immediately after you confirm.

🏛️ Quick Reference — Buttons & Controls

All toolbar buttons, checkboxes, and keyboard shortcuts for Sakarto dHash duplicate finder
Button / ActionWhat it does
🔄 New SearchReload the page and start a fresh scan
📋 Copy (N)Copy selected filenames to clipboard. N = count selected.
📂 Move (N)Move selected files or stage them in the Move Queue
🗑️ Delete (N)Delete selected files or stage them in the Delete Queue
✕ Deselect AllRemove selection from all cards
⚖️ Compare (N)Open the compare modal for Ctrl+clicked files. Needs 2+.
🔇 VideosToggle mute/unmute for all video cards
Queue Mode checkboxWhen checked: stage files for review before executing. Recommended.
Fast Mode checkboxUse EXIF thumbnail for JPEG scanning — much faster. On by default.
Scan Images checkboxInclude or exclude image files from the scan
Scan Videos checkboxInclude or exclude video files from the scan
Similarity Threshold sliderMaximum Hamming distance for grouping. Lower = stricter. Re‑clusters on release.
Click cardSelect / deselect the file
Ctrl + Click cardAdd / remove from compare list (purple border)
Click & drag (empty area)Box‑select multiple cards at once
Ctrl + dragAdd to existing selection with box
Right‑click cardContext menu: Copy / Move / Delete / Compare
🔍 hover iconOpen full‑size preview with metadata and action buttons
Hover video cardAuto‑play the video clip

⭐ What Users Say

Based on 172 reviews

"I had hundreds of photos with different brightness levels from various cameras. dHash grouped them perfectly — exposure differences didn't fool it at all. A fantastic tool for cleaning up inconsistent photo collections."

"dHash caught duplicates that aHash completely missed because the images were exposure‑corrected. The gradient‑based approach is brilliant for real‑world photo libraries where brightness isn't consistent."

"I use dHash as my first pass for any folder where I know there are exposure variants. It's fast and reliable. I then use Color Signature for colour‑based duplicates. A great combination."

"I run a photo restoration business and dHash is perfect for finding different versions of the same scanned photo — brightness and contrast vary so much between scans, but dHash handles it effortlessly."

💡 Tips for Best Results

Back Up First

Always back up your files before deleting anything. Deleted files bypass the recycle bin and cannot be recovered.

Use dHash for Exposure‑Corrected Photos

If you have photos that were edited with brightness or contrast adjustments, dHash will catch them where aHash might not — because it records gradient direction, not absolute brightness.

Start at the Default Threshold

The default of 10 is well‑calibrated for dHash. Lower it if you want only very close matches; raise it if you know the copies have more significant edits applied.

Compare Before Deciding

Ctrl+Click two cards then click Compare to see them side‑by‑side with the similarity percentage. dHash can occasionally group different scenes with similar compositional lines — always visually verify before deleting.

Move, Don't Delete

Use Move to a “Sakarto‑Duplicates” folder rather than deleting outright. Review the moved files over a few days before permanently removing anything.

Combine Algorithms for Tough Collections

Run dHash for brightness/color variants, then run pHash for subtle edits, and ORB for rotated copies. Different passes with different algorithms will catch different kinds of duplicates.

⚠️ Known Limitations

Rotation and mirroring break matching.

A 90° rotation transposes horizontal gradients to vertical, completely changing the hash. A mirrored copy reverses gradient directions. For rotation‑tolerant matching, use ORB Feature Matching.

Heavy cropping shifts edge positions in the grid.

If a large portion of the image is cropped away, the remaining content maps to a different part of the 16×16 grid, producing a different hash. For heavily cropped versions, try pHash or ORB.

Color is not compared — only brightness gradients.

Like aHash and BlockHash, dHash converts to grayscale before processing. A colorful version and a desaturated version of the same image may match perfectly if their brightness gradients align. This is usually desirable behaviour but worth knowing.

No undo for file deletion.

The File System Access API bypasses the OS recycle bin. Deleted files are gone permanently. Use Queue Mode to review before executing.

Video scanning pauses when you switch tabs.

Browsers throttle background video decoding. Video processing pauses when the tab is hidden and resumes when you return. Image hashing (in the Web Worker) continues at full speed regardless.

Move and Delete require Chrome or Edge.

The File System Access API is only available in Chrome 86+ and Edge 86+. Firefox and Safari can scan and display results but cannot move or delete files. Use “Download List” to export results in those browsers.

🔒 Privacy & Security

Zero network activity after page load. Open DevTools → Network tab and verify: no outbound requests during any scan, hash computation, or file operation.
No accounts, no cookies, no analytics. The only localStorage data saved is your OS detection and checkbox preferences. No file names, paths, or hashes are ever saved or transmitted.
Folder access is scoped and session‑only. Permission is granted only for the specific folder you select, lasts only while the tab is open, and is revocable at any time from browser site settings.
Purely static — no backend. Sakarto is HTML, CSS, and JavaScript. There is no server, no database, and no API receiving your data.

❓ Frequently Asked Questions

How is dHash different from aHash, BlockHash, and pHash?
All four produce a binary hash compared with Hamming distance, but they encode different image properties. aHash compares each pixel in a 16×16 grid to the overall mean brightness — it captures coarse light/dark layout. BlockHash averages 16×16 blocks and compares each to the median — more tolerant of compression noise but even coarser. pHash applies a Discrete Cosine Transform and encodes the dominant low‑frequency content — the most precise of the four. dHash is unique: it compares each pixel to its right‑hand neighbour, encoding the direction of brightness change rather than absolute brightness. This makes dHash insensitive to overall brightness level — the same image processed at a different exposure or brightness setting will produce the same dHash, because the relative ordering between adjacent pixels doesn't change when you uniformly raise or lower brightness.
Why exactly is dHash good at finding brightness‑adjusted copies?
When you increase the overall brightness of an image, every pixel gets lighter by roughly the same amount. Pixel A might go from value 80 to 120, and its right neighbour B might go from 60 to 100. Before the adjustment: A (80) > B (60) — the bit is 1. After: A (120) > B (100) — the bit is still 1. The relative ordering is preserved. dHash records this ordering for all 256 adjacent pixel pairs, so uniform brightness and contrast adjustments leave the hash almost completely unchanged. The edge case is extreme adjustment that flattens gradients to near‑zero — if adjacent pixels become nearly identical (all white or all black), the relative ordering becomes noise‑driven and the hash degrades.
Two clearly different photos are being grouped together. How do I fix it?
dHash encodes edge and gradient structure, not image content. Photos with similar compositional lines — two corridor shots, two aerial field photos, two portraits with similar lighting direction — can have similar gradient patterns without being the same image. Lower the threshold slider to 5–8 to require much closer gradient matches. If false positives persist, try pHash (frequency‑domain content, more discriminating) or Color Signature (also compares colour). Always use the Compare modal to verify before acting on any group.
I know two files are duplicates but they aren't being grouped. What should I try?
First, raise the threshold toward 15–20. Second, check aspect ratios — pairs differing by more than 10% are excluded by the pre‑check. Third, consider the type of edit: dHash handles brightness and contrast changes well, but significant colour grading that shifts where gradients appear, heavy cropping, or rotation will break the match. For rotated copies, use ORB. For colour‑graded copies where the subject and composition are the same but hues have shifted, try dHash at a higher threshold or pHash as an alternative.
What does Fast Mode do, and is it safe to leave on?
Fast Mode reads the small EXIF thumbnail embedded in JPEG files (usually 160×120 pixels) instead of decoding the full image. This is 5–10× faster with negligible accuracy loss for dHash, because dHash's 17×16 pixel basis is tiny relative to most EXIF thumbnails. Leave Fast Mode on unless you notice unexpected groupings on JPEG files that go away when Fast Mode is off — which would suggest those files lack EXIF thumbnails and Fast Mode is falling back to partial data.
Can dHash find HDR vs standard versions of the same photo?
Usually yes, depending on how the HDR processing was applied. HDR processing typically boosts local contrast — bringing up shadow areas and pulling down highlight areas. This changes the absolute brightness of pixels but often preserves the direction of brightness gradients between adjacent pixels. If the HDR version simply applies global tone mapping (brightening overall), dHash will match it confidently. If it applies heavy local tone mapping that reverses local gradients in shadow or highlight regions, some bits will flip and matching will depend on how many gradients were reversed relative to the threshold.
Why does video scanning pause when I switch tabs?
Browsers throttle background video element processing when a tab is hidden, stopping frame extraction. Sakarto detects this via the Page Visibility API and pauses video scanning automatically, resuming the moment you return. Image hashing runs entirely in a background Web Worker, which is not subject to tab‑visibility throttling — images keep scanning at full speed no matter which tab you're viewing.
Can I recover files after deleting them?
No. The File System Access API's remove() method bypasses the OS Recycle Bin entirely and permanently deletes files. Queue Mode is on by default to prevent accidents: files are staged for review before execution. Before deleting, use the full‑size preview icon and the Compare modal to verify the files in each group. If in doubt, Move to a “Sakarto‑Duplicates” subfolder first — you can always delete from there later once you're certain.
What file types are supported?
Images: JPEG, PNG, GIF, WebP, BMP. Videos: MP4, WebM, MOV, MKV. Files over 40 MB are skipped. HEIC/HEIF, SVG, RAW formats, and TIFF are not supported due to browser decoder limitations. Convert RAW or HEIC files to JPEG or PNG in your photo editor before scanning.
Does this work on Firefox or Safari?
Scanning, hash computation, result display, and the Compare modal all work in Firefox and Safari. Move and Delete require the File System Access API (Chrome 86+ and Edge 86+ only). In other browsers, scan and review results normally, then use Download List to export a report and handle files manually.