You need to share a screenshot of a bug, a payment dashboard, or a support conversation, and an API key or customer email sits right in the middle of it. Most people grab the nearest editor, drag a Gaussian blur over the secret, and hit send.
That smudge looks impenetrable. It is not. Blur rearranges pixel information rather than deleting it, and text is unusually easy to reconstruct because attackers know which fonts screenshots use. Pixelation is better, but it has its own published attacks. Only an opaque fill removes the content outright.
This guide explains the mechanics behind each method, the attacks that defeat them, and the block-size thresholds that matter for real Retina screenshots.
What Each Redaction Method Leaks
flowchart TD
S["Sensitive text in a screenshot"] --> B["Gaussian blur"]
S --> F["Pixelation: blocks smaller than the glyphs"]
S --> C["Pixelation: blocks larger than the line height"]
S --> O["Solid opaque box"]
B -->|"Deconvolution or font-matched forward search"| BR["Often recoverable"]
F -->|"Depix / Unredacter dictionary matching"| FR["Often recoverable"]
C -->|"Glyph shapes averaged away"| CR["Length and color leak, characters do not"]
O -->|"Output independent of input"| OR["Only box size leaks"]
style BR fill:#ffe4e6,stroke:#e11d48,color:#9f1239
style FR fill:#ffe4e6,stroke:#e11d48,color:#9f1239
style CR fill:#fef9c3,stroke:#ca8a04,color:#713f12
style OR fill:#d1fae5,stroke:#059669,color:#065f46
Why Gaussian Blur Fails as Redaction
Blur is a linear convolution
A Gaussian blur replaces every pixel with a weighted average of its neighbors. The weights come from a 2D bell curve, the point spread function (PSF):
G(x, y) = 1 / (2πσ²) · exp(−(x² + y²) / 2σ²)
The blurred pixel is the sum of every neighbor multiplied by its weight. Here σ (sigma) is the standard deviation, which sets the effective blur radius.
Three properties make this a poor redaction primitive:
- It is linear and deterministic. The same input and the same σ always produce the same output.
- It is overlapping. Every neighborhood shares pixels with the next one, so information about each glyph is spread across many output pixels instead of being thrown away.
- Its frequency response never hits zero. In the Fourier domain, blurring multiplies the image spectrum by another Gaussian. That attenuates fine detail sharply but never cancels it exactly.
Inverting blur: deconvolution
Because the spectrum is attenuated rather than zeroed, classical Wiener deconvolution and iterative Richardson-Lucy deconvolution can boost the suppressed high frequencies back up, provided the attacker can estimate σ. In practice, 8-bit quantization and JPEG noise bury the weakest frequencies, so pure deconvolution struggles against very large radii.
The attack that actually works: forward search
Attackers rarely need to invert anything. Screenshot text has strong priors:
- Known typefaces: San Francisco on macOS and iOS, Segoe UI on Windows, Roboto on Android, and a handful of web fonts.
- Fixed glyph geometry: every “7” in a given font and size has identical outlines.
- High contrast: dark text on a light background, or the reverse.
So the attacker renders candidate strings in the matching font, blurs them with the same σ, and keeps whichever candidate’s blurred output best matches the target. No inversion is required, and noise matters far less. Hill, Zhou, Saul, and Shacham formalized this in On the (In)effectiveness of Mosaicing and Blurring as Tools for Document Redaction (PETS 2016), using hidden Markov models to decode blurred and mosaiced text across typefaces, sizes, and noise levels.
Note: Generative “AI unblur” upscalers are a different thing. They invent plausible detail, which can look convincing but be wrong. Forward search is the reliable attack because it checks each guess against the actual pixels.
Pixelation: Better, but Not Automatically Safe
How mosaic pixelation works
Pixelation splits the region into a grid of non-overlapping B×B tiles, reduces each tile to a single color (typically the mean of its pixels), and paints that color across the whole tile.
A 20×20 tile holds 400 RGB samples, or 1,200 values. Pixelation reduces them to 3. Unlike blur, the stroke curves and anti-aliasing inside each tile are genuinely discarded, and many different inputs map to the same output.
Why pixelation is still crackable: Depix and Unredacter
Block averaging is still a linear, deterministic operation. It cannot be inverted, but it can be attacked with the same forward-search idea as blur:
- Depix (Sipke Mellema, 2020) is built specifically for pixelated screenshots. The attacker types a De Bruijn sequence, a string containing every short character combination, in the same font, size, and editor, then pixelates it with the same block size. Depix matches target tiles against those reference tiles and uses their geometric arrangement to discard false matches and rebuild the text.
- Unredacter (Bishop Fox, 2022) handled cases Depix could not, including unknown grid offsets, by searching over candidate characters and alignments.
Both attacks rely on blocks that are small relative to the glyphs, so each character still leaves a distinctive tile pattern.
The threshold that matters: blocks versus line height
Once a single tile spans several characters plus the whitespace around them, those per-glyph patterns disappear. What remains is the text’s approximate length, its color, and its rough word boundaries.
The trap is device pixel ratio. macOS and iOS screenshots are stored at 2× or 3× resolution, so text is much taller in image pixels than it looks:
| Source | CSS font size | Approx. em height in the image | Block size that is still “micro” |
|---|---|---|---|
| Windows at 100% scaling | 14px | ~14px | Under ~14px |
| MacBook Retina (2×) | 16px | ~32px | Under ~32px |
| iPhone (3×) | 17px | ~51px | Under ~51px |
A 14px mosaic that looks adequate on a 1× Windows capture can leave every letter of a Retina screenshot covered by several distinctive tiles. Measure the text in the actual image, then choose a block size at least as large as the full line height, and drag the selection past the text so the edge tiles mix in background pixels.
Solid Opaque Redaction: The Only Zero-Content Option
When you paint a solid rectangle (for example #000000) over a region, every covered pixel gets the same constant value no matter what was underneath. The output carries no information about the covered content. In information-theory terms, the mutual information between the hidden text and that patch of output is zero, because the output never changes.
That makes a solid box the right default for passwords, API keys, card and ID numbers, and legal exhibits. Two caveats remain:
- Box geometry leaks length. A box hugging an 8-character password says “8 characters”. Make the box wider than the text, and use one box rather than one per word.
- Context leaks too. Check for partially covered descenders, cursor carets, autocomplete suggestions, browser tab titles, and the same secret appearing elsewhere in the screenshot.
For PDFs, drawing a box is not enough, because the text survives underneath in the file. See how to redact a PDF properly or use the Redact PDF tool.
Redaction Method Comparison
| Criterion | Gaussian Blur | Fine Mosaic (block smaller than glyphs) | Coarse Mosaic (block at least the line height) | Solid Opaque Box |
|---|---|---|---|---|
| Operation | Overlapping weighted average | Non-overlapping block average | Non-overlapping block average | Constant overwrite |
| Linear and deterministic? | Yes | Yes | Yes | Output is constant |
| Invertible? | Partially (spectrum never reaches zero) | No, but forward search works | No | No |
| Published practical attacks | Deconvolution; HMM font matching (Hill et al., 2016) | Depix (2020), Unredacter (2022), HMM matching | None known when tiles span several glyphs | None against content |
| What still leaks | Most low-frequency structure | Per-glyph tile patterns | Length, color, word gaps | Box size |
| Appropriate for | Aesthetic softening only | Pixel art | Names, emails, and chat text in routine screenshots | Passwords, keys, card and ID numbers |
A caution about coarse mosaics: if the hidden value comes from a tiny set of possibilities, such as a 4-digit PIN or a yes/no field, an attacker can render every option and compare tile colors directly. Use a solid box for those.
How Utiliome’s Pixelate Tool Renders the Mosaic
Utiliome’s Pixelate Image Tool runs entirely in the browser using the HTML5 Canvas 2D API. Here is the core of the actual implementation, with the optional grid overlay omitted:
// Excerpt: packages/widgets/src/pixelate-image/PixelateImageWidget.tsx
const createPixelatedCanvas = (
img: HTMLImageElement,
w: number,
h: number,
blockSize: number,
showGrid: boolean
): HTMLCanvasElement => {
const out = document.createElement('canvas');
out.width = w;
out.height = h;
const ctx = out.getContext('2d');
if (!ctx) return out;
const size = Math.max(2, blockSize);
const sw = Math.max(1, Math.round(w / size));
const sh = Math.max(1, Math.round(h / size));
const small = document.createElement('canvas');
small.width = sw;
small.height = sh;
const sCtx = small.getContext('2d');
if (sCtx) {
sCtx.imageSmoothingEnabled = true;
sCtx.drawImage(img, 0, 0, sw, sh); // 1. Downscale: one pixel per tile
ctx.imageSmoothingEnabled = false;
ctx.drawImage(small, 0, 0, sw, sh, 0, 0, w, h); // 2. Nearest-neighbor upscale
} else {
ctx.drawImage(img, 0, 0, w, h);
}
// ...optional grid lines drawn here when showGrid && size >= 6
return out;
};
What this means in practice:
- Tile colors come from the browser’s resampler. The image is downscaled to one pixel per tile with smoothing on. The widget does not set
imageSmoothingQuality, and the HTML spec leaves the downscaling filter to the browser, so each tile is a browser-filtered summary of its block rather than a guaranteed exact arithmetic mean. Do not count on that as protection: an attacker can reproduce the exact output by pushing reference text through the same browser at the same block size. Block size relative to the text is what matters. - Tiles stay crisp. Upscaling with
imageSmoothingEnabled = falsegives nearest-neighbor scaling, so tiles keep hard edges with no bilinear halos. - Tile size is approximate. The grid uses
Math.round(w / blockSize)tiles, so a 1170px-wide screenshot at 28px ends up with 42 columns of about 27.9px each. - Censor Box mode clips a full-image mosaic. In
regionmode the original image is drawn first, then the mosaic layer is drawn through a rectangular clip (ctx.rect(...)followed byctx.clip()). The grid is anchored to the image’s top-left corner, not to your box, so edge tiles can include pixels from just outside the selection.
Other behavior verified in the source:
- Block size: a 2px–100px slider plus presets for 8-Bit (6px), Mosaic (14px), Censor (28px), and Redact (50px).
- Output: PNG by default. JPG and WebP are encoded at quality 0.92, and JPG exports get a white
#FFFFFFmatte behind transparent areas. - Batch: several images can be processed and downloaded together as
pixelated-images.zip, built with JSZip. - No solid-fill mode. The tool produces mosaics only. For passwords and keys, use any editor’s opaque rectangle tool instead.
Warning: Exported files are named like
screenshot_pixelated_28px.png. That filename tells an attacker your exact block size, which is one of Depix’s inputs. Rename the file before sharing anything sensitive.
The page makes no network request containing your image. Downloads only push an anonymous analytics event: tool name, block size, and mode for a single download, or tool name and file count for a ZIP. Image bytes and filenames are never included, and you can confirm this in your browser DevTools Network tab.
When the Blur Tool Is the Right Choice
Blur is still useful when nothing secret is involved. Utiliome’s Blur Image Tool suits softening busy backgrounds behind hero text, or creating a depth-of-field look with its Focus Box (outside) mode, which keeps a region sharp and blurs everything around it. Under the hood, it draws the image onto a transparent canvas padded by Math.ceil(radius * 2) pixels, then composites a ctx.filter = blur(...) copy over the sharp original. Near the image borders, the blurred layer is partly transparent, so some of the sharp original still shows through. That is one more reason never to treat it as redaction for text.
Pre-Share Redaction Checklist
- 1. No blur on text. Never use blur for passwords, keys, account numbers, names, or emails.
- 2. Solid box for secrets. Credentials, card and ID numbers, and anything drawn from a small set of possible values get an opaque box that is wider than the text.
- 3. Size mosaics in image pixels. For routine PII, set the block size to at least the text’s line height in the actual screenshot. On 2× Retina captures that usually means at least the Redact (50px) preset rather than Mosaic (14px). On 3× iPhone captures, go above 50px with the slider.
- 4. Pad the selection. Extend the Censor Box beyond the text so edge tiles mix in background pixels.
- 5. Flatten and inspect. Export a flat PNG, JPG, or WebP, never a layered file, then open the downloaded file and zoom in to confirm the region is covered.
- 6. Strip the hints. Rename files that include the block size, and check the rest of the screenshot for the same secret in tab titles, URLs, or autocomplete.
Blur fails because it spreads information instead of removing it. Small-block pixelation fails because each glyph still leaves a fingerprint. A coarse mosaic sized to the real text height covers everyday PII, and a solid box is the only method that hides the content itself.