Cleaning up documents with the Linux Document Scanner
Document Cleanup lets the end user erase unwanted artifacts from a scanned page while preserving the underlying document content. Artifacts include handwriting, stamps, stains, fingers, shadows, and other distracting elements. The user paints over the regions to remove. The SDK then reconstructs a clean result image, with optional text preservation.
Cleaning up an image
The examples below load a source image and a matching mask image, create a DocumentCleanup pipeline, run one cleanup pass, and optionally save the result to disk.
- Python
- Java
- NodeJS
- C
loading...
loading...
loading...
loading...
Configuration options
Configure the cleanup behavior of the underlying engine through DocumentCleanupConfiguration. In the Ready-to-Use UI, pass it as screens.cleanup.engineConfiguration.
| Property | Type | Default | Description |
|---|---|---|---|
keepText | Boolean | true | If true, the SDK keeps detected text intact while the user erases around it. Text detection runs once up front and can take a moment, so construct the cleanup pipeline asynchronously to keep the UI responsive. |
maxUndoRedoStackSize | Int | 3 | How many undo and redo steps the SDK keeps in memory. 0 turns off undo and redo. When the limit is exceeded, the oldest steps can no longer be undone. |
maxCleanupResolution | Int | 0 | Caps the brushed area the SDK processes in one cleanup step, as width × height in pixels. Larger areas are processed at a lower resolution and scaled back up, which saves memory but can soften the edges near the stroke. 0 means no limit. For example, 1200000 keeps peak memory at about 0.5 GB for a 12 MP image. Prefer cleaning smaller areas over relying on this limit. |
maxMaskBoundingBoxArea | Int | 600000 | Caps the area of the bounding box around the brushed mask, as width × height in pixels. If the mask is larger, the SDK skips the cleanup and returns the unchanged image with the status ERROR_MASK_TOO_LARGE. The undo and redo history stays as it is. Unlike maxCleanupResolution, this limit rejects the mask instead of lowering the quality, so you can ask the user to select a smaller area. 0 means no limit. |
Cleanup status
A cleanup run reports a DocumentCleanupStatus alongside the resulting image:
| Value | Meaning |
|---|---|
OK | Cleanup completed at full resolution. |
OK_BUT_REDUCED_QUALITY | Cleanup completed, but maxCleanupResolution forced an internal downscale of the cleanup region, so quality near the cleanup boundary may be reduced. If the result is not good enough, undo the last operation and apply cleanup on a smaller area. |
ERROR_MASK_TOO_LARGE | The cleanup didn't run because the bounding box of the mask exceeds maxMaskBoundingBoxArea. The returned image is unchanged and the undo and redo history stays as it is. Retry with a smaller mask or raise the limit. |
Undo, redo, reset
DocumentCleanup is stateful across run(mask) calls. Each successful cleanup pushes a new entry onto an internal undo stack (limited by maxUndoRedoStackSize):
- Undo reverts the last cleanup and returns the previous image. If no operation is available, the current image is returned unchanged.
- Redo re-applies the last undone cleanup. Performing a new cleanup after an undo clears the redo history.
- Reset restores the original input image and clears the undo/redo history. After reset, both
canUndoandcanRedoreturnfalse.
- Python
- Java
- NodeJS
- C
| Method | Description |
|---|---|
cleanup.undo() | Revert the last cleanup. Returns the current image. |
cleanup.redo() | Re-apply the last undone cleanup. Returns the current image. |
cleanup.reset() | Restore the original image and clear the history. |
cleanup.can_undo() | True if an undo operation is available. |
cleanup.can_redo() | True if a redo operation is available. |
| Method | Description |
|---|---|
cleanup.undo() | Revert the last cleanup. Returns the current image. |
cleanup.redo() | Re-apply the last undone cleanup. Returns the current image. |
cleanup.reset() | Restore the original image and clear the history. |
cleanup.canUndo() | true if an undo operation is available. |
cleanup.canRedo() | true if a redo operation is available. |
| Method | Description |
|---|---|
await cleanup.undo() | Revert the last cleanup. Returns the current image. |
await cleanup.redo() | Re-apply the last undone cleanup. Returns the current image. |
await cleanup.reset() | Restore the original image and clear the history. |
await cleanup.canUndo() | true if an undo operation is available. |
await cleanup.canRedo() | true if a redo operation is available. |
| Function | Description |
|---|---|
scanbotsdk_document_cleanup_undo(cleanup, &image) | Revert the last cleanup and return the current image. |
scanbotsdk_document_cleanup_redo(cleanup, &image) | Re-apply the last undone cleanup and return the current image. |
scanbotsdk_document_cleanup_reset(cleanup, &image) | Restore the original image and clear the history. |
scanbotsdk_document_cleanup_can_undo(cleanup, &result) | Writes true into result if an undo operation is available. |
scanbotsdk_document_cleanup_can_redo(cleanup, &result) | Writes true into result if a redo operation is available. |
Want to scan longer than one minute?
Generate a free trial license to test the Scanbot SDK thoroughly.
Get free trial licenseScanbot SDK is part of the Apryse SDK product family
A mobile scan is just the start. With Apryse SDKs, you can expand mobile workflows into full cross‑platform document processing. Whether you need to edit PDFs, add secure digital signatures, or use a fast, customizable document viewer and editor, Apryse gives you the tools to build powerful features quickly.
Learn more
