Redact Image

Helps a redacted screenshot stay redacted: solid boxes only, padded to whole pixels, flattened into a fresh PNG that is re-checked on export.

StopsRedacted screenshot still readable

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/redact-image.json

The files land in your project. They're yours to edit.

Usage

redact-image-usage.tsx
import { findSensitiveText, RedactImage, type DetectedWord } from "@/components/ui/redact-image"

<RedactImage
  src={shot.url}
  alt="Billing screenshot with a customer's email, card number and API key"
  defaultValue={email ? [email] : []}
  detect={() => findSensitiveText(shot.words)}
/>

What it catches

  • Blur or pixelation used as redaction (only solid fills are offered)
  • Box edges that leave half-covered pixels, by padding and snapping outward
  • Sensitive text your detector finds but no box covers
  • Metadata and trailing data after the image end (aCropalypse-style), by re-encoding to a fresh PNG
  • Boxes that are not solid in the exported file, by re-reading it

Props

RedactImage props
PropTypeDefault
src* (required)

The screenshot. Must be same-origin, a data: URL or a blob: URL so it can be flattened.

string—
alt

Accessible description of the screenshot.

string—
value

Controlled redaction boxes, in image pixels.

Region[]—
defaultValue

Initial boxes when uncontrolled.

Region[][]
onValueChange

Called when boxes are drawn, accepted or removed.

(boxes: Region[]) => void—
detect

Pluggable text detector. Return regions to suggest, e.g. `findSensitiveText(ocrWords)`.

(image: HTMLImageElement) => Region[] | Promise<Region[]>—
padding

Pixels added around every box so glyph edges can't leak.

number2
fill

Box colour as RGB. Always fully opaque.

[number, number, number][0, 0, 0]
onExport

Called with the flattened, verified PNG.

(blob: Blob, report: RedactionReport) => void—
fileName

File name of the download.

string"redacted.png"
messages

Every visible string (see `REDACT_IMAGE_MESSAGES`).

Partial<RedactImageMessages>—
exportLabelstring—

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Boxes can be moved with arrow keys and removed with Delete or Backspace
  • Each suggestion and remove button has an aria-label; hints wired with aria-describedby
  • Scan and export progress announced in polite live regions; export failures use role=alert
  • Undo and Add-box are regular buttons; icons are aria-hidden

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: If the image is uploaded, store only the exported PNG and strip metadata again server-side; never keep the original.

  • Only as good as the detector you plug in; it does not run OCR by itself
  • Cannot catch information outside the boxes you or the detector mark (faces, reflections, context)
  • The original image stays in memory until you discard it; only the export is cleaned

What it stops

Redacted screenshot still readable

Also known as

redact · screenshot · blur · censor · image editor · privacy · bug report · black box

Field type

Dependencies

Pairs well with