AI-powered text removal from manga, manhua, and comic images.
⚠️ IMPORTANT DISCLAIMER: PROVIDED AS-ISThis software is provided as-is, without warranty of any kind, express or implied. Use at your own risk. The authors and contributors are not responsible for any damage, data loss, or issues arising from the use of this software. Always backup your original images before processing.
- Features
- Installation
- Quick Start
- Usage
- Configuration
- Architecture
- Plugin System
- Troubleshooting
- Limitations
- OCR-based text detection using PaddleOCR or EasyOCR
- AI-powered inpainting with FLUX.2-klein and LongCat models
- Smart fill optimization for simple backgrounds (reduces AI workload)
- Batch processing for entire folders
- Character whitelist to preserve SFX, symbols, or specific text
- Supercanvas PSD export for long-strip comics, with each cleaned page as a layer
- Plugin system for extensibility
- Modern PyQt6 GUI with live preview
- Command-line interface for automation
- Clean Architecture - modular, testable, maintainable
- Python 3.10 or higher
- CUDA-capable GPU recommended (8GB+ VRAM for AI models)
- 16GB+ RAM recommended for batch processing
The package uses optional dependencies to keep the core lightweight:
# Minimal install - core only (50MB, no GPU needed)
# Use this if you only need the domain logic and utilities
pip install manhua-cleaner
# With OCR support - adds PaddleOCR (~500MB)
pip install manhua-cleaner[ocr]
# With AI models - adds PyTorch + Diffusers (~5GB, requires GPU)
pip install manhua-cleaner[models]
# With GUI - adds PyQt6 (~200MB)
pip install manhua-cleaner[gui]
# With quantization support - adds SDNQ/DFloat11
pip install manhua-cleaner[quantization]
# Everything included (full installation ~6GB)
pip install manhua-cleaner[all]
# CPU-only install (OCR only, no AI models)
pip install manhua-cleaner[ocr,gui]# Check available plugins
python -c "from manhua_cleaner.infrastructure import PluginRegistry; \
print('OCR:', PluginRegistry.list_available_ocr()); \
print('Models:', PluginRegistry.list_available_models())"# Launch the PyQt6 graphical interface
manhua-cleaner-gui# Process a single image
manhua-cleaner image.jpg -o output/
# Process an entire folder
manhua-cleaner ./manga_chapter/ -o ./cleaned/
# Use LongCat model with 8 steps
manhua-cleaner ./images/ -o ./out/ -m LongCat-Image-Edit-Turbo -s 8
# Full options example
manhua-cleaner ./images/ -o ./out/ \
--model FLUX.2-klein-4B \
--device cuda \
--steps 4 \
--expand 25 \
--smart-fill-expand 5 \
--prompt "remove all text and speech bubbles" \
--whitelist --whitelist-preset sfx_only \
--verboseThe GUI provides a visual interface with:
- Input/Output selection - File or folder browsing
- Model selection - Choose AI model and device
- Parameters panel - Steps, expansion, smart fill settings
- OCR settings - Backend selection, precision, workers
- Whitelist configuration - Preserve specific text patterns
- Output exports - Save per-image PSD sidecars or one stacked supercanvas PSD
- Live preview - See results before/after processing
- Progress tracking - Real-time processing status
manhua-cleaner-gui| Argument | Short | Default | Description |
|---|---|---|---|
input |
- | - | Input image file or folder |
--output |
-o |
- | Output folder (required) |
--model |
-m |
FLUX.2-klein-4B | AI model to use |
--device |
-d |
auto | Compute device (auto/cuda/mps/cpu) |
--steps |
-s |
model default | Number of inference steps |
--expand |
-e |
25 | Pixels to expand text boxes |
--smart-fill-expand |
- | 5 | Smart fill expansion (smaller than AI) |
--prompt |
-p |
"remove all text" | Inpainting prompt |
--verbose |
-v |
- | Enable verbose output |
| Argument | Description |
|---|---|
--no-color-correct |
Disable color correction |
--no-smart-fill |
Disable smart fill optimization |
--no-edge-blend |
Disable edge blending |
--extra-pass |
Enable extra quality pass (provide prompt) |
--export-psd |
Export a layered PSD sidecar for each cleaned image |
--supercanvas |
Export one long-strip PSD with each cleaned image as its own layer |
--continue-on-error |
Continue batch processing on failure |
| Argument | Default | Description |
|---|---|---|
--ocr-model |
paddleocr | OCR backend (paddleocr/easyocr) |
--ocr-version |
v1.5 | PaddleOCR pipeline version (v1.6/v1.5/v1.0) |
--ocr-precision |
fp16 | OCR precision (fp16/fp32) |
--no-ocr-tensorrt |
- | Disable TensorRT acceleration |
--ocr-workers |
1 | Parallel OCR workers (VRAM intensive) |
| Argument | Description |
|---|---|
--whitelist |
Enable whitelist filtering |
--whitelist-preset |
Use built-in preset (none/sfx_only/hearts/symbols/japanese_sfx) |
--whitelist-file |
Load patterns from JSON/text file |
--whitelist-patterns |
Custom regex patterns (space-separated) |
--whitelist-distance |
Max distance for text grouping (default: 50px) |
# Basic usage
manhua-cleaner manga_page.jpg -o cleaned/
# Batch processing with specific model
manhua-cleaner ./chapter_01/ -o ./cleaned/ \
--model LongCat-Image-Edit-Turbo \
--steps 8 \
--device cuda
# Export one editable long-strip PSD after batch processing
manhua-cleaner ./chapter_01/ -o ./cleaned/ --supercanvas
# Preserve SFX symbols using whitelist
manhua-cleaner manga.jpg -o out/ \
--whitelist \
--whitelist-preset sfx_only \
--whitelist-distance 30
# Custom whitelist patterns
manhua-cleaner manga.jpg -o out/ \
--whitelist \
--whitelist-patterns "^[!?]+$" "^[♡♥❤]+$"
# Load whitelist from file
manhua-cleaner manga.jpg -o out/ \
--whitelist \
--whitelist-file patterns.txt
# High-quality processing with extra pass
manhua-cleaner cover.jpg -o out/ \
--steps 12 \
--extra-pass "enhance quality, sharpen details"
# Batch processing with error tolerance
manhua-cleaner ./batch/ -o ./out/ \
--continue-on-error \
--verbose
# CPU-only processing (no GPU)
manhua-cleaner manga.jpg -o out/ \
--device cpu \
--ocr-model easyocrfrom manhua_cleaner import BatchProcessor, ProcessingConfig, ModelType
# Create configuration
config = ProcessingConfig(
model_type=ModelType.FLUX_2_KLEIN_4B,
steps=4,
expand_pixels=25,
smart_fill=True,
smart_fill_expand_pixels=5,
prompt="remove all text"
)
# Process with automatic cleanup
processor = BatchProcessor(config)
with processor:
result = processor.process_image("page_01.jpg")
if result.success:
print(f"Smart filled: {result.boxes_smart_filled}")
print(f"AI processed: {result.boxes_processed}")
result.image.save("cleaned_01.jpg")from manhua_cleaner.domain.entities.image import Image
from manhua_cleaner.domain.value_objects.config import ProcessingConfig, ModelType
from manhua_cleaner.application.services.text_removal import TextRemovalService
from manhua_cleaner.infrastructure.plugin_registry import PluginRegistry
# Create engines via plugin system
ocr = PluginRegistry.create_ocr_engine('paddleocr')
model = PluginRegistry.create_model('flux')
# Configure
config = ProcessingConfig(
model_type=ModelType.FLUX_2_KLEIN_4B,
steps=4,
expand_pixels=25,
whitelist_enabled=True,
whitelist_preset='hearts'
)
# Create service
service = TextRemovalService(
ocr=ocr,
image_model=model,
config=config
)
# Process with context manager
with service:
result = service.remove_text("manga_page.jpg")
if result.success:
print(f"Processing time: {result.processing_time_ms}ms")
result.image.save("cleaned.jpg")from manhua_cleaner.application.ports.event_publisher import ProcessingEvent
# Subscribe to processing events
def on_event(event: ProcessingEvent):
print(f"[{event.stage}] {event.message}")
if event.progress:
print(f"Progress: {event.progress:.0%}")
service.subscribe_to_events(on_event)| Model | Parameters | Default Steps | VRAM | Speed | Quality |
|---|---|---|---|---|---|
| FLUX.2-klein-4B | 4B | 4 | ~8GB | Fast | Good |
| FLUX.2-klein-9B | 9B | 4 | ~16GB | Fast | Better |
| FLUX.2-klein-9B-SDNQ-4bit | 9B (quantized) | 4 | ~6GB | Fast | Good |
| LongCat-Image-Edit | - | 50 | ~12GB | Medium | Excellent |
| LongCat-Image-Edit-Turbo | - | 8 | ~12GB | Fast | Good |
| LongCat-Image-Edit-DF11 | - (quantized) | 50 | ~8GB | Medium | Good |
| Preset | Description |
|---|---|
none |
No whitelisting |
sfx_only |
SFX symbols (!?…〜) |
punctuation |
Ending punctuation |
hearts |
Heart symbols (♡♥❤) |
symbols |
Music notes, stars (♪♫★☆) |
japanese_sfx |
Japanese SFX characters |
This project uses Clean Architecture with clear separation of concerns:
manhua_cleaner/
├── domain/ # Pure business logic, zero dependencies
│ ├── entities/ # Image, TextRegion, ProcessingResult
│ ├── value_objects/ # Config, Geometry types
│ └── services/ # Box merging, smart fill, text grouping
├── application/ # Use cases and orchestration
│ ├── ports/ # Interfaces (OCREngine, ImageModel)
│ └── services/ # TextRemovalService, BatchProcessor
├── adapters/ # External integrations
│ ├── models/ # FLUX, LongCat implementations
│ ├── ocr/ # PaddleOCR, EasyOCR implementations
│ └── persistence/ # File I/O, caching
├── infrastructure/ # Plugin system, utilities
└── interfaces/ # CLI, GUI, API
- Dependency Inversion - Domain depends on nothing
- Plugin System - Extensible via entry points
- Lazy Loading - Heavy deps only loaded when needed
- Protocol-based - Structural typing with Python protocols
The plugin system allows third-party developers to add new OCR engines or AI models without modifying the core codebase.
- Implement the port interface:
# my_ocr_plugin.py
from manhua_cleaner.application.ports.ocr_engine import OCREngine, TextDetectionResult
class MyOCR(OCREngine):
@property
def name(self) -> str:
return "MyCustomOCR"
def detect(self, image):
# Your implementation
return TextDetectionResult(regions=[...])- Register via entry points in your
pyproject.toml:
[project.entry-points."manhua_cleaner.ocr"]
my_ocr = "my_ocr_plugin:MyOCR"- Users can now use your plugin:
manhua-cleaner image.jpg -o out/ --ocr-model my_ocrmanhua_cleaner.ocr- OCR enginesmanhua_cleaner.models- AI image models
- Purpose: Preserve specific text (SFX, symbols) while removing other text
- How it works: Groups nearby text regions and checks if combined text matches whitelist patterns
- Usage: Enable with
--whitelistand choose a preset or custom patterns - Presets:
sfx_only- Keeps punctuation and SFX symbols (!?…〜)hearts- Keeps heart symbols (♡♥❤)symbols- Keeps music notes, stars (♪♫★☆)japanese_sfx- Keeps Japanese SFX characters
- Example:
--whitelist --whitelist-preset sfx_only
- Purpose: Automatically fill text on simple/monochromatic backgrounds without using AI
- How it works: Checks color variance around text region edges; if low variance, fills with average color
- Benefit: Can reduce AI workload by up to 80% in images with simple backgrounds
- Usage: Enabled by default (
--smart-fill-expandcontrols expansion) - Note: May occasionally fill unintended areas if background near text is complex
- Purpose: Expands text bounding boxes before smart fill analysis
- How it works: Adds padding around detected text regions to include context
- Default: 5 pixels (smaller than AI expand)
- Trade-off: Higher values reduce eligible regions (more goes to AI); lower values may miss text edges
- Usage:
--smart-fill-expand 10
- Purpose: Expands text bounding boxes before AI inpainting
- How it works: Grows the polygon around detected text to give AI context
- Default: 25 pixels
- Trade-offs:
- Higher values: More context for AI, but slower and may affect unintended areas
- Lower values: Faster, but may cause color shifting with some models
- Usage:
--expand 30
- Purpose: Fixes color shifts from AI processing
- How it works: Detects color difference between edges of original and processed regions, applies correction
- Usage: Enabled by default; disable with
--no-color-correct - When to disable: If you notice unwanted color changes in processed areas
- Purpose: Blends processed regions with original image for natural transitions
- How it works: Applies gradient fade at boundaries of filled regions
- Usage: Enabled by default; disable with
--no-edge-blend - Note: Helps hide boundaries between original and AI-generated content
- Purpose: Run AI model a second time on the entire image for quality improvement
- Use cases:
- Upscale the image
- Apply overall quality enhancement
- Fix remaining artifacts from first pass
- Usage:
--extra-pass "improve image quality" - Note: Balloons processing time; best for low quality images or images with undetecatable text
- Purpose: Increase image resolution before extra pass
- How it works: Upscales image using Lanczos/bicubic/bilinear, then AI adds detail
- Options: 1.5x, 2x, 3x, 4x, 8x
- Methods: Lanczos (best quality), Bicubic (balanced), Bilinear (fastest)
- Usage: Available in GUI; for CLI use Python API
- Purpose: Parallel OCR processing for batch operations
- How it works: Each worker loads a separate OCR model instance
- Default: 1 worker
- Warning: Each worker uses ~16GB VRAM - increase with caution
- Usage:
--ocr-workers 2(only if you have 32GB+ VRAM)
- Options: v1.6, v1.5 (default), v1.0
- Usage:
--ocr-version v1.5 - PaddleOCR-VL-1.6: Requires
paddleocr>=3.6.0
- Options: fp16 (default), fp32
- fp16: Half precision, faster, uses less VRAM
- fp32: Full precision, more accurate, slower
- Usage:
--ocr-precision fp32(if OCR misses text)
- Purpose: Don't stop batch processing if one image fails
- Usage:
--continue-on-error - Behavior: Logs errors, continues with remaining images, reports failures at end
# Use quantized models
manhua-cleaner image.jpg -o out/ --model FLUX.2-klein-9B-SDNQ-4bit
# Reduce batch size (process fewer at once)
# Close other GPU applications# Increase expansion
manhua-cleaner image.jpg -o out/ --expand 40
# Try different OCR backend
manhua-cleaner image.jpg -o out/ --ocr-model easyocr
# Use FP32 precision for better accuracy
manhua-cleaner image.jpg -o out/ --ocr-precision fp32# Enable smart fill
manhua-cleaner image.jpg -o out/ --smart-fill-expand 10
# Use Turbo models
manhua-cleaner image.jpg -o out/ --model LongCat-Image-Edit-Turbo --steps 8
# Reduce inference steps
manhua-cleaner image.jpg -o out/ --steps 4# If you get "No module named torch"
pip install manhua-cleaner[models]
# If you get "No module named paddleocr"
pip install manhua-cleaner[ocr]
# If you get "No module named PyQt6"
pip install manhua-cleaner[gui]-
Quality Variability: AI inpainting quality varies based on image complexity, text size, and background detail. Results are not guaranteed.
-
Processing Time: AI models are computationally intensive. A single image may take 10-60 seconds depending on settings and hardware.
-
VRAM Requirements: AI models require significant GPU memory. Ensure you have sufficient VRAM or use quantized models.
-
OCR Accuracy: Text detection depends on image quality. Low-resolution, blurry, or highly stylized text may be missed.
-
Backup Your Data: Always keep originals. The software may occasionally produce unsatisfactory results that require manual touch-ups.
-
As-Is Software: This software is provided without warranty. Use at your own risk.
# Install dev dependencies
pip install manhua-cleaner[dev]
# Run tests
pytest manhua_cleaner/tests/ -v
# Run with coverage
pytest --cov=manhua_cleaner --cov-report=htmlmanhua_cleaner/
├── domain/ # Zero-dependency business logic
│ ├── entities/ # Core domain objects
│ ├── value_objects/ # Immutable config/geometry
│ └── services/ # Pure business logic
├── application/ # Use cases
│ ├── ports/ # Abstract interfaces
│ └── services/ # Orchestration
├── adapters/ # External implementations
├── infrastructure/ # Plugin system
└── interfaces/ # CLI/GUI
<<<<<<< HEAD GPLv3 - See LICENSE file for details.
======= See LICENSE file for details.
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
YOU USE THIS SOFTWARE ENTIRELY AT YOUR OWN RISK. ALWAYS BACKUP YOUR ORIGINAL IMAGES.
f9d6c2b (changed readme)