RedactOffline

How RedactOffline finds and removes text from photos

RedactOffline reads text out of a photo using Apple's Vision framework, sorts what it finds into typed categories like phone number or IBAN, and then permanently overwrites the pixels in those regions when you redact. There's no server involved at any step — detection, classification, and the final export all run in the app, on the phone, with no network calls.

Summary:

  • Text detection uses Apple's Vision framework (VNRecognizeTextRequest), not a custom OCR model or a third-party library.
  • An on-device classifier sorts recognized text into typed categories, validating credit card numbers with the Luhn algorithm and IBANs with the mod-97 checksum.
  • On iOS 26 and later, an additional Apple Intelligence pass can flag more categories, such as dates of birth and national ID numbers; below iOS 26 the app relies on the classifier alone.
  • Every redaction style — solid fill, which is free, and blur and pixelate, which the one-time purchase unlocks — is rendered through CIContext.createCGImage, which flattens the result into a new single-plane bitmap with no separate, removable redaction layer.
  • The exported image is a freshly built file; the app has no network code, so nothing about the photo or its text is ever transmitted anywhere.

Apple’s Vision framework does the reading

Apple's Vision framework, specifically VNRecognizeTextRequest. This is the same underlying technology behind Apple's Live Text feature. RedactOffline runs the request in .accurate recognition mode when you actually redact an image, and in the faster .fast mode for the live preview while you're framing a photo, so the interface stays responsive without sacrificing accuracy on the result that matters. There is no Core ML model bundled with the app and no third-party OCR library — Vision does the recognition work.

Checksums decide what a number actually is

An on-device classifier looks at each recognized text region and sorts it into a typed category: email address, link, phone number, street address, person name, credit card number, IBAN, or a passport/ID machine-readable zone (MRZ). Credit card numbers are checked against the Luhn algorithm, the same checksum used to validate card numbers before submission. IBANs are checked against the mod-97 checksum defined in the IBAN standard. Both checks reduce false positives — a random 16-digit number that fails Luhn isn't flagged as a card number. You can also add your own custom terms — a name, a project codename, an internal account number — and the app will look for exact matches on every photo you open.

On an iPhone running iOS 26 or later, an additional Apple Intelligence pass adds detection for a few more categories: date of birth, national ID number, username, and a general "other sensitive" bucket. Below iOS 26, that pass doesn't run, and the app relies on the on-device classifier alone — detection still works, just without those extra categories.

Redacting rewrites the pixels, it doesn’t cover them

There are three redaction styles: solid fill, included in the free version, and blur and pixelate, which are unlocked by the one-time $6.99 purchase. All three go through the same rendering step: CIContext.createCGImage, which renders a Core Image pipeline into a brand-new CGImage — a single flat bitmap. Solid fill composites a CIConstantColorGenerator over the selected region. Blur and pixelate blend a filtered copy of the image through a mask covering the same region. Either way, the output is one flattened image with new pixel values baked in — there's no separate "redaction layer" sitting on top of the original that could later be hidden, moved, or deleted. See why blurred screenshots can be unredacted for what that flattening does and doesn't guarantee against.

The unredacted original stays only in memory, as Data held by the editing session, for as long as you're working on that photo. It's not written into the exported file and isn't recoverable from it.

Every export builds a new file

Three export paths, all producing a new file:

The export path builds a fresh UIImage from the re-rendered CGImage; it doesn't carry forward the original file's CGImageSource metadata dictionary. In practice, that means location and camera metadata (EXIF/GPS) from the original photo are not carried into the redacted image — it's a side effect of rebuilding the image from scratch, not a separate "strip metadata" step. RedactOffline doesn't explicitly re-encode or recompress the image either; the final file format (typically HEIC or JPEG) and compression are decided by Photos or whatever app receives the share, based on your system settings.

Nothing touches the network

There are zero network calls anywhere in the codebase. There's no analytics SDK, no crash reporter, and no telemetry. The app's PrivacyInfo.xcprivacy file declares no tracking and no collected data types; the only declared API-access reason in the whole app is for reading UserDefaults. The single exception to "no contact with any Apple service" is StoreKit 2, used for the one-time Pro purchase — that's the only network-capable code path in the app, and it only runs when you choose to buy.

Limitations

  • iPhone only — no iPad, Mac, or Android build.
  • Requires iOS 16.0 or later; the Apple Intelligence detection pass requires iOS 26+.
  • Detects text, not faces. RedactOffline does not do face detection or face blurring.
  • Images only — no PDF support, no video support.
  • Automatic language detection covers English (en-US) and German (de-DE) by default; Dutch (nl-NL) is added at runtime if the device has the Dutch Vision model installed.

If you'd rather see this from the other end — what you actually tap, and how to do it without opening the app at all — the step-by-step guide covers both routes.