iOS · Vision · Flick

Not a Single Photo Uploaded: Flick's On-Device Similar Photo Detection

Analyzing the photo library entirely on device with Vision feature prints, Laplacian variance, and a SQLite cache.

Flick is a swipe-to-clean photo app. Its two core capabilities – finding similar photos and finding blurry photos – both run entirely on device, with no server dependency and no third-party SDKs. This post covers how it works.

Similarity detection: Vision feature prints

Apple’s Vision framework provides VNGenerateImageFeaturePrintRequest: feed it an image, get back a feature vector (feature print). The closer the distance between two images’ vectors, the more similar their content:

let request = VNGenerateImageFeaturePrintRequest()
try VNImageRequestHandler(cgImage: image).perform([request])
let print = request.results?.first as? VNFeaturePrintObservation
// print.computeDistance(_:to:) gives the distance between two images

Once I have vectors for the whole library, I cluster them by a distance threshold, and scenarios like burst shots, duplicate screenshots, and pick-one-of-nine all land in the same group. What’s left is presenting each group to the user and letting them swipe to keep one.

Blur detection: Laplacian variance

The classic way to tell whether a photo is blurry is to run a Laplacian convolution over the image and compute the variance: sharp images have rich edges and high variance, blurry ones have low variance. Using vImage for the convolution and vDSP for the variance, it’s a few milliseconds per image – fast enough on pure CPU. The algorithm is decades old and needs no machine learning model.

Engineering details

  • Feature caching: with tens of thousands of photos, recomputing on every launch is out of the question. Feature vectors go into SQLite – straight C API, no ORM; at this scale that’s plenty.
  • Analysis pipeline: a background coordinator processes in batches and is cancelable at any point, so the first full analysis doesn’t cook the device.
  • iCloud placeholder files: on devices with iCloud Photos storage optimization enabled, many “photos” only exist locally as thumbnails. For these, read the metadata only and skip analysis – never trigger a download, or the user’s cellular data and iCloud storage both take the hit.

Why fully on-device, no exceptions

Privacy isn’t a slogan here; it’s decided by the architecture: with no server, “photos being uploaded” isn’t even a possible problem, and the privacy policy only needs one sentence. There’s a side benefit for an indie developer too – zero server cost. Every copy of the app sold is pure margin, with no monthly bill.