Check Whether the Blacked-Out Text in a PDF Is Really Gone
By Aldridge Dagos, operations software engineer
A black rectangle can hide a line on a PDF page without removing the text underneath it. The page looks finished. A person who copies or extracts its text may still recover the supposedly hidden line.
You can inspect that difference without using a real person’s information. The exercise below puts an invented account marker into an original PDF, covers it in one copy and applies redaction in another. A separate metadata field and attachment make the second part of the problem visible: removing the selected line does not automatically remove everything elsewhere in the file.
The short version: Use a genuine redaction operation, apply it and save a separate output. Reopen that exact file. Try selecting and searching for the removed text, then extract page text with an independent reader where possible. Inspect other relevant content, including metadata, annotations and attachments. A failed search is useful evidence about one path, not a certificate that every disclosure route has been removed. Test only with fictional information while learning the method.
The PyMuPDF redaction API distinguishes adding a redaction annotation from applying the redactions. The fixture uses the library locally. It was prepared on October 29, 2026, and its marker strings are invented. It is not a processed client document or a general-purpose sanitization service.
How can a rectangle leave the text available?
A PDF can contain drawing commands and text on the same page. Adding a filled shape over a text item changes what you see without necessarily deleting the item. The important question is what the resulting file still contains, not how convincing the shape looks at a particular zoom level.
Open rectangle-only example (PDF). Its account marker is obscured by an ordinary black rectangle. Try selecting the line or searching for DEMO-481516. Text extracted from this saved file still contains that invented marker. That is an actual result from the saved exercise file, not an assumption based on its appearance.
Compare it with applied-redaction example (PDF). In that copy, the script added and applied a redaction for the marker’s location. Text extracted from that saved copy no longer contains DEMO-481516. A nearby ordinary sentence remains, providing a useful check that the test did not merely destroy the entire page.
Both pages can present a dark block in roughly the same place. Looking at the block alone does not tell you which operation occurred. This is why “I opened it and the text was blacked out” is not a sufficient review record.
The sender benefits from a check that can catch an accidental disclosure. The recipient benefits from receiving a document whose withheld material has actually been handled, rather than being placed in the awkward position of discovering hidden text that nobody intended to share.
Inspect the saved file 01
A black page can conceal different underlying states.
Black rectangle
Page textStill extractable
Elsewhere in the PDFMetadata and attachment remain
Targeted redaction
Page textTarget absent in page-text check
Elsewhere in the PDFMetadata and attachment still remain
Known fixture fields removed
Page textTarget absent in page-text check
Elsewhere in the PDFKnown metadata and attachment removed
Check the file that was saved, not only the page that was displayed.
What does applying redaction do that drawing does not?
A redaction tool identifies regions to process and then applies an operation to the underlying content. Merely placing a redaction annotation is not the same as applying it. In PyMuPDF, the relevant methods are documented separately. A script or interface needs to carry the work through to the saved output.
The example’s page was intentionally simple. It contains ordinary text at known positions. The script finds the invented marker, marks its rectangle for redaction and applies the operation. It then writes a new PDF with garbage collection rather than relying on a screenshot of the open document.
# Illustrative example using the downloadable rectangle-only PDF.
# Requires PyMuPDF. Review its licence before reuse.
import pymupdf
with pymupdf.open("covered-only.pdf") as document:
page = document[0]
for region in page.search_for("DEMO-481516"):
page.add_redact_annot(region, fill=(0, 0, 0))
page.apply_redactions()
document.save("my-redacted-copy.pdf", garbage=4, deflate=True)
This is deliberately not a recipe that accepts arbitrary documents and announces that they are safe. The coordinates, object types and content relationships in a different PDF can require different treatment. The library’s redaction options distinguish text from images and graphics, and those choices deserve review against the actual page.
I would keep the script’s promise narrow: remove one known page-text marker, save a separate copy, then check what a reader can still extract. The output still needs the other checks below.
Why can the selected text be gone while other information remains?
The fixture includes an invented subject in its document metadata and a small attached text file. Neither lives in the account marker’s page rectangle. Applying that page redaction therefore leaves them available in the targeted-redaction example.
The table below separates the checks. In the targeted-redaction copy, the page-text marker is absent while the metadata subject DEMO-METADATA-7391 and one embedded attachment remain. A successful page-text check therefore leaves two other known disclosure paths unresolved.
That result is useful precisely because it refuses an easy pass. A script checking only the page text would report success while leaving a separate part of the exercise untouched. The test would have answered its own question correctly and the larger sharing decision incompletely.
The PyMuPDF document API exposes metadata and embedded files separately. Removing a page-text marker does not remove those other objects. Inspect each relevant part of the saved document before deciding what can be shared.
| Downloadable example | Target in extracted page text | Known metadata and attachment |
|---|---|---|
covered-only.pdf |
Present | Present |
target-redacted.pdf |
Absent in this check | Still present |
Both examples deliberately retain those separate disclosure paths. Neither is presented as a completely sanitized document. A real file may contain information in places that a small fictional exercise did not anticipate.
How should you inspect the saved output?
First reopen the file you intend to distribute. Check its filename and location. It is surprisingly easy to inspect the processed copy and later attach the original because both are still open and their names differ by one suffix.
Search for the withheld term and try selecting across the blacked-out region. Copy the surrounding passage into a plain-text editor. Those actions can expose retained text through the viewer you already use. They should be part of a broader inspection, not the only tests you perform.
The exercise also includes a parser-based check. The following shape reads an output rather than modifying it:
# Read the actual saved copy. This checks page text only.
import pymupdf
with pymupdf.open("target-redacted.pdf") as document:
extracted = "\n".join(page.get_text() for page in document)
print("DEMO-481516" in extracted)
For the supplied target-redacted fixture, the result is false. For the covered-only fixture, it is true. The comparison is stronger than an isolated failed search because it includes a positive control: the same extraction method can find the planted marker before it is removed.
- Page contents: Inspect the actual region and the surrounding material after applying redaction.
- Other document content: Review the relevant metadata, annotations and embedded items using suitable tools.
- Saved-file identity: Make sure the file inspected is the one selected for distribution.
- Verification scope: Record which checks were performed and what they can establish.
If the output contains scanned page images, an ordinary text extraction may find nothing even before you begin. That does not mean the visible information has been removed. Use tests appropriate to the original representation rather than celebrating a method that could never see it.
What should the person doing the work avoid promising?
Avoid saying that failed search proves complete sanitization. A parser may not expose every representation in a complex document. An image can still display information even when no page-text object contains it. An attachment can remain available outside the page you inspected.
Avoid implying that a crop is equivalent to removing content. If a tool changes what is displayed, establish what it does to the underlying file before treating that action as redaction. The same discipline applies to flattened annotations and exported copies. Inspect the output rather than relying on the name of the command.
Some documents also carry signatures or other features that editing can affect. If the document must retain a particular legal or evidentiary status, use a workflow approved for that purpose. This fictional exercise does not resolve those requirements and should not be offered as a compliance certificate.
The human-review path is a useful companion when a document cannot pass the required checks. Stop the distribution step and name the unresolved condition. Do not let a successful local script run become authority to release material whose contents you have not resolved.
This is not an argument against using a capable redaction tool. It is an argument for making the tool’s result inspectable. A sender should be able to say what was removed, which output was checked and what remains uncertain without reconstructing the process from memory.
The review record needs privacy care of its own. Do not copy a real withheld identifier into an ordinary ticket merely to prove that a search was performed. You could remove the identifier from the document while preserving it in a less controlled place. Use a suitable reference to the reviewed item and record the method and outcome without casually duplicating the private value.
The fictional fixture avoids that problem by making every marker publishable. In a real workflow, the ability to inspect the original may itself require restricted access. Give the reviewer what they need through the approved route rather than forwarding the untouched source to everyone involved in the release.
Also distinguish an unsuccessful inspection from a successful removal. If a reader cannot open an encrypted file or the extraction tool exits with an error, the missing search result is not a pass. Resolve the access or parser condition first. An unanswered question should remain unanswered instead of being converted into a clean-looking check mark.
How can you use the example without exposing private documents?
Open the two fictional PDFs linked above in your own reader. Search for DEMO-481516, inspect the document properties and look for the embedded attachment. Those are separate checks: the table shows what was found in the prepared examples. No private document is needed to try them.
The prepared example used PyMuPDF 1.26.5. The source fragment above is provided under AGPL-3.0-or-later. PyMuPDF itself has AGPL and commercial licensing, described in its licence documentation. Review those terms before incorporating the example into a proprietary application.
The tool dependency is separate from the lesson. You can inspect the generated PDFs without adopting that library for your own product. You can also use another redaction application, provided you verify the result with methods appropriate to its output.
For private material, reducing unnecessary copies still matters. A successful redaction does not erase the untouched originals scattered across downloads and working folders. Keep what is required under an intentional retention rule, and choose the outgoing copy deliberately.
The difference between evidence and a plausible-looking answer is not confined to generated text. A black rectangle can be very persuasive. Give it a saved-file check before giving it your trust.
Frequently asked questions
How do I check PDF redaction instead of trusting the black box?
Reopen the saved output, search for the removed term and try copying the surrounding text. Add appropriate extraction and document-content checks. Use a known original or fictional control to establish that your method could detect the information before removal.
Is drawing a black rectangle enough to remove PDF text?
Not in the supplied example. The rectangle hides the invented marker visually while page-text extraction still returns it. Use a genuine redaction operation and apply it, then inspect the saved result rather than treating the shape as proof.
Does a failed text search prove that all private information is gone?
No. Images, metadata, attachments and other content may require separate inspection. A text extraction that could not detect the original information cannot establish its removal. The fixture demonstrates known paths, not complete sanitization of arbitrary PDFs.
Are the account references in the download real?
No. Every marker, metadata value and attachment in the exercise is invented. The files were prepared on October 29, 2026 to make the differences inspectable without using a private record or implying a client result.
Can I put the example script into a closed commercial application?
Do not assume that from the download. The script uses PyMuPDF, whose AGPL and commercial licensing require review for the intended use. The exercise provides source and a bounded demonstration, not permission advice for a proprietary product.
Publication details
This article belongs to the editorial calendar. First published .