A web-based document scanning application using Windows Image Acquisition (WIA). The application consists of two services: a scanner service that interfaces with physical scanners, and a web server that provides the user interface.
This application is designed for proof-of-concept and demonstration purposes only.
It does NOT include security features required for production environments:
- ❌ No authentication or authorization mechanisms
- ❌ No input validation or sanitization
- ❌ No rate limiting or abuse prevention
- ❌ No secure API secret management (hardcoded placeholders)
- ❌ No HTTPS/TLS encryption
- ❌ Debug mode enabled by default
- ❌ No file upload validation or scanning for malicious content
- ❌ No CSRF protection
DO NOT use this application in production without implementing proper security measures, including but not limited to: secure authentication, input validation, encrypted communications, secret management, and comprehensive error handling.
Two scanner service implementations are available:
-
Python Implementation (
scanner.py) - Included in this repository- Python-based using pywin32 for WIA communication
- Suitable for simple deployments and development
-
.NET Scanner Agent - Separate repository
- C# worker service implementation
- Repository: https://github.com/weekmo/scanneragent
- Alternative to
scanner.pywith same REST API interface - Can be used as a drop-in replacement for the Python scanner service
- Installable as a Windows service for automatic startup
Both implementations provide the same /scan endpoint and return base64-encoded images.
- WIA scanner integration for Windows-compatible scanners
- Browser-based interface accessible over network
- Configurable DPI (default 300) and color modes
- Automatic image storage with UUID-based filenames
- Base64 image transfer via REST API
- Image preview in browser
The application uses a two-server architecture:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Web Browser │────────▶│ Web Server │ │ Scanner Service│
│ (Port 5000) │ │ webserver.py │◀────────│ scanner.py │
│ │ │ (Port 5000) │ AJAX │ (Port 5001) │
└─────────────────┘ └──────────────────┘ └────────┬────────┘
│ │
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ uploads/ │ │ Physical Scanner│
│ (Image Storage)│ │ (WIA Device) │
└─────────────────┘ └──────────────────┘
-
Scanner Service - Port 5001
- Interfaces with Windows Image Acquisition (WIA) API
- Provides REST endpoint
/scanto trigger scans - Returns base64-encoded image data
- Must run on the machine with the physical scanner
- Can use either
scanner.py(Python) or Scanner Agent (.NET/C#)
-
Web Server (
webserver.py) - Port 5000- Serves the HTML user interface
- Handles image upload and storage
- Can run on any machine (same or different from scanner)
-
Web Interface (
templates/index.html)- Single-page application with scan button
- Displays scanned images in real-time
- Provides visual feedback during scanning
- Operating System: Windows (for WIA scanner support)
- Python: 3.7 or higher (for webserver.py and scanner.py)
- .NET: .NET 6.0 or higher (if using Scanner Agent instead of scanner.py)
- Scanner: WIA-compatible scanner (most modern scanners)
Flask==3.1.2
flask-cors==6.0.2
Pillow==12.1.0
pywin32==311
-
Clone or download this repository
cd scanner_python -
Install dependencies
pip install -r requirements.txt
Dependencies are already installed from step 2 above.
-
Clone the Scanner Agent repository:
git clone https://github.com/weekmo/scanneragent.git
-
Follow the build and installation instructions in the Scanner Agent repository.
- Ensure your scanner is connected and powered on
- Install manufacturer drivers if needed
- Test scanner functionality with Windows Scan app
You need to run both services (can be in separate terminal windows):
Terminal 1: Start the Scanner Service
Option A - Python Scanner:
python scanner.pyOption B - .NET Scanner Agent:
# Follow the run instructions from the Scanner Agent repositoryOutput: Running on http://0.0.0.0:5001
Terminal 2: Start the Web Server
python webserver.pyOutput: Running on http://0.0.0.0:5000
- Open a web browser
- Navigate to:
http://localhost:5000 - Click "Scan Document" button
- The scanner will activate and scan the document
- The scanned image will appear in the browser
- Image is automatically saved to
uploads/directory
To scan from other devices on your network:
-
Find the scanner machine's IP address:
ipconfig
-
On the scanner machine, both services should already be listening on
0.0.0.0 -
On other devices, access the web interface at:
http://<scanner-machine-ip>:5000 -
Update the
SCANNER_URLintemplates/index.htmlif needed:const SCANNER_URL = 'http://<scanner-machine-ip>:5001';
Edit scanner.py to modify default scan parameters:
# In the /scan endpoint
raw = wia_scan_to_image_bytes(
color_mode="Color", # Options: "Color", "Grayscale"
dpi=300, # Resolution: 75, 150, 300, 600, etc.
format="PNG" # Options: "PNG", "JPEG", "BMP", "TIFF"
)- Web Server: Change port in
webserver.py(line:app.run(port=5000)) - Scanner Service: Change port in
scanner.py(line:app.run(port=5001))
Images are saved to uploads/ by default. Change in webserver.py:
UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), 'uploads')scanner_python/
├── scanner.py # Scanner service (WIA interface)
├── webserver.py # Web server and upload handler
├── requirements.txt # Python dependencies
├── README.md # This file
├── LICENSE # License information
├── templates/
│ └── index.html # Web interface
└── uploads/ # Scanned images (created automatically)
└── scan_*.png # Saved scans
- Verify scanner is powered on and connected
- Check Windows Device Manager for scanner
- Install manufacturer's WIA drivers
- Try using Windows Scan app first
- Ensure both services are running
- Check firewall settings allow ports 5000 and 5001
- Verify
SCANNER_URLin HTML matches scanner service location
- Increase DPI in
scanner.py(e.g., 600 DPI) - Clean scanner glass
- Check scanner settings in manufacturer software
- flask-cors should handle this automatically
- Verify
CORS(app)is present inscanner.py - Check browser console for specific CORS messages
Both services run with debug=True by default:
- Auto-reloads on code changes
- Provides detailed error messages
- Not recommended for production use
Possible extensions:
- Multiple scanner support: Modify device selection in
wia_scan_to_image_bytes() - PDF generation: Use
Pilloworreportlabto convert images to PDF - OCR: Integrate
pytesseractfor text extraction - Batch scanning: Add queue system for multiple pages
For production deployment:
- Disable debug mode (
debug=False) - Implement authentication (Flask-Login, OAuth)
- Use HTTPS (Flask-Talisman, reverse proxy)
- Validate and sanitize all inputs
- Limit file upload sizes
- Restrict network access with firewall rules
This project is licensed under the terms included in the LICENSE file.
Mohammed Abdelgadir
Last Updated: January 2026