A powerful tool for analyzing text-background contrast ratios in UI screenshots using PaddleOCR and K-means clustering to ensure WCAG accessibility compliance.
- Automatic Text Detection: Uses PaddleOCR to automatically detect and extract text regions from UI screenshots
- Intelligent Color Extraction: Employs K-means clustering to accurately identify text and background colors
- WCAG Compliance Checking: Validates contrast ratios against WCAG 2.1 AA and AAA standards
- Multiple Output Formats: Generate reports in both JSON and human-readable text formats
- Easy to Use: Simple CLI and Python API for seamless integration
- Comprehensive: Analyzes all text regions in an image with detailed results
- Python 3.10 or higher
- uv - Fast Python package and project manager
If you don't have uv installed:
# On macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# On Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# Or via pip
pip install uvgit clone https://github.com/longway-code/ContrastCheck.git
cd ContrastCheck
# Create virtual environment with uv (Python 3.10+)
uv venv --python 3.10
# Activate virtual environment
# On macOS/Linux:
source .venv/bin/activate
# On Windows:
.venv\Scripts\activate
# Install the package
uv pip install -e .# Production dependencies
uv pip install -r requirements.txt
# Development dependencies
uv pip install -r requirements-dev.txtPaddleOCR 3.x automatically detects and uses GPU when available. For GPU support, install the GPU version of PaddlePaddle:
uv pip uninstall paddlepaddle
uv pip install paddlepaddle-gpuNote: The --gpu flag is deprecated in PaddleOCR 3.x and will be ignored. GPU acceleration is automatically enabled when GPU and CUDA are available.
Analyze a UI screenshot:
contrastcheck your_screenshot.pngGenerate a JSON report:
contrastcheck your_screenshot.png -f json -o report.jsonAnalyze with large text threshold:
contrastcheck your_screenshot.png --large-textfrom contrast_check.main import ContrastAnalyzer
# Initialize analyzer
# Note: use_gpu parameter is deprecated in PaddleOCR 3.x+
# GPU is automatically detected and used when available
analyzer = ContrastAnalyzer(lang='en')
# Analyze image
results = analyzer.analyze_image('screenshot.png')
# Print results
for result in results:
print(f"Text: {result['text']}")
print(f"Contrast Ratio: {result['contrast_ratio']}:1")
print(f"WCAG AA: {'PASS' if result['wcag_aa'] else 'FAIL'}")
print()
# Generate report
report = analyzer.generate_report(results, output_format='text')
print(report)- Text Detection: PaddleOCR identifies all text regions in the screenshot and extracts their bounding boxes
- Color Extraction:
- Text colors are extracted from pixels within the detected text regions
- Background colors are sampled from areas surrounding the text
- K-means clustering identifies the dominant colors
- Contrast Calculation: Calculates relative luminance and contrast ratios according to WCAG 2.1 guidelines
- Compliance Check: Compares ratios against WCAG AA (4.5:1 normal, 3:1 large) and AAA (7:1 normal, 4.5:1 large) thresholds
- WCAG AA: Minimum contrast ratio of 4.5:1
- WCAG AAA: Minimum contrast ratio of 7:1
- WCAG AA: Minimum contrast ratio of 3:1
- WCAG AAA: Minimum contrast ratio of 4.5:1
================================================================================
CONTRAST ANALYSIS REPORT
================================================================================
Total text regions analyzed: 3
--------------------------------------------------------------------------------
Text #0: Sign In
OCR Confidence: 95.2%
Text Color: RGB(0, 0, 0) (#000000)
Background Color: RGB(255, 255, 255) (#ffffff)
Contrast Ratio: 21.0:1
WCAG AA: ✓ PASS
WCAG AAA: ✓ PASS
Level: Excellent (AAA)
--------------------------------------------------------------------------------
Text #1: Username
OCR Confidence: 92.8%
Text Color: RGB(102, 102, 102) (#666666)
Background Color: RGB(255, 255, 255) (#ffffff)
Contrast Ratio: 5.7:1
WCAG AA: ✓ PASS
WCAG AAA: ✗ FAIL
Level: Good (AA)
================================================================================
SUMMARY
================================================================================
WCAG AA Compliance: 3/3 (100.0%)
WCAG AAA Compliance: 2/3 (66.7%)
================================================================================
[
{
"index": 0,
"text": "Sign In",
"confidence": 0.952,
"text_color": [0, 0, 0],
"text_color_hex": "#000000",
"bg_color": [255, 255, 255],
"bg_color_hex": "#ffffff",
"contrast_ratio": 21.0,
"wcag_aa": true,
"wcag_aaa": true,
"level": "Excellent (AAA)"
}
]usage: contrastcheck [-h] [-o OUTPUT] [-f {json,text}] [--large-text]
[--gpu] [--lang LANG] image
positional arguments:
image Path to the UI screenshot image
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
Output file path for the report
-f {json,text}, --format {json,text}
Output format (default: text)
--large-text Treat all text as large text (18pt+ or 14pt+ bold)
--gpu Deprecated. GPU is auto-detected by PaddleOCR 3.x+
--lang LANG Language for OCR (default: en)
ContrastCheck/
├── contrast_check/ # Main package
│ ├── __init__.py
│ ├── ocr_extractor.py # OCR text extraction
│ ├── color_extractor.py # Color extraction using K-means
│ ├── contrast_checker.py # Contrast ratio calculation
│ └── main.py # Main application and CLI
├── tests/ # Unit tests
│ ├── test_ocr_extractor.py
│ ├── test_color_extractor.py
│ ├── test_contrast_checker.py
│ └── test_main.py
├── examples/ # Usage examples
│ └── simple_usage.py
├── requirements.txt # Production dependencies
├── requirements-dev.txt # Development dependencies
├── setup.py # Package setup
├── pytest.ini # Pytest configuration
├── LICENSE # MIT License
└── README.md # This file
# Create virtual environment with Python 3.10+
uv venv --python 3.10
# Activate virtual environment
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install in development mode with dev dependencies
uv pip install -e ".[dev]"Run all tests:
pytestRun with coverage:
pytest --cov=contrast_check --cov-report=htmlRun specific test file:
pytest tests/test_contrast_checker.pyFormat code with Black:
black contrast_check/ tests/Check code style:
flake8 contrast_check/ tests/Sort imports:
isort contrast_check/ tests/Type checking:
mypy contrast_check/- PaddleOCR: Text detection and recognition
- OpenCV: Image processing
- scikit-learn: K-means clustering for color extraction
- NumPy: Numerical computations
- Pillow: Image handling
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- PaddleOCR for the excellent OCR engine
- WCAG 2.1 Guidelines for accessibility standards
- The open-source community for continuous support
If you use ContrastCheck in your research or project, please cite:
@software{contrastcheck2026,
title = {ContrastCheck: UI Screenshot Contrast Ratio Analyzer},
author = {ContrastCheck Contributors},
year = {2026},
url = {https://github.com/longway-code/ContrastCheck}
}If you encounter any issues or have questions:
- Open an issue on GitHub
- Check the examples directory for usage examples
- Read the WCAG 2.1 documentation for accessibility guidelines
- Support for multiple languages in OCR
- Batch processing of multiple images
- Visual output with highlighted regions
- Web interface for easy access
- Integration with CI/CD pipelines
- Support for PDF documents
- Color blindness simulation
Made with ❤️ for better web accessibility