Scandalous is a cross-platform Avalonia desktop application for scanning documents and exporting them as PDF files. It uses the NAPS2 SDK for scanner access, image processing, OCR, and PDF generation.
- Discovers and scans with platform-appropriate scanner backends:
- Windows: WIA
- macOS: eSCL-compatible network scanners discovered through Bonjour (
dns-sd) - Linux: SANE
- Supports Color, Grayscale, and Black & White scanning.
- Supports feeder duplex, feeder simplex, and flatbed paper sources.
- Offers 150, 300, 600, and 1200 DPI scan resolutions.
- Can automatically deskew pages and exclude blank pages.
- Exports pages as either one combined PDF or separate PDFs.
- Prompts for additional pages when using a flatbed with combined-PDF output.
- Shows the most recently scanned page in the preview area and reports scan progress.
- Can apply Tesseract OCR to create searchable PDFs.
- Remembers scan settings, output location, selected scanner, and window state.
- Opens a completed combined PDF in the system's default PDF viewer.
- Provides validation and user-friendly errors for common scanner and file problems.
To build and run from source:
- .NET 10 SDK
- A compatible scanner and any drivers or backend required by your operating system
- macOS: an eSCL-compatible scanner available on the local network
- Windows: a scanner available through WIA
- Linux: a scanner available through SANE
The macOS publishing script creates a self-contained application bundle, so the resulting app does not require a separate .NET runtime installation.
Key NuGet dependencies include:
Avalonia12.1.0CommunityToolkit.MvvmMicrosoft.Extensions.DependencyInjectionNAPS2.SdkNAPS2.Images.ImageSharpNAPS2.Tesseract.Binaries
Restore dependencies:
dotnet restoreBuild the Avalonia application:
dotnet build Scandalous.Avalonia/Scandalous.Avalonia.csprojOr build the entire solution, including the core library and tests:
dotnet build Scandalous.slnRun the application in Debug mode:
dotnet run --project Scandalous.Avalonia/Scandalous.Avalonia.csproj --configuration DebugIn Visual Studio or Rider, open Scandalous.sln, set Scandalous.Avalonia as the startup project, and press F5.
Run the tests:
dotnet test Scandalous.Core.Tests/Scandalous.Core.Tests.csprojThe included script publishes a self-contained macOS .app bundle.
Apple Silicon (osx-arm64, the default):
./publish-mac.shIntel Mac (osx-x64):
./publish-mac.sh osx-x64The finished bundle is written to publish/Scandalous.app. You can run it directly or drag it into /Applications.
If the script is not executable, run this once:
chmod +x publish-mac.shTo create a self-contained publish directory without assembling an .app bundle, use the .NET CLI directly:
# Apple Silicon
dotnet publish Scandalous.Avalonia/Scandalous.Avalonia.csproj \
-c Release -r osx-arm64 --self-contained true -o publish/out
# Intel Mac
dotnet publish Scandalous.Avalonia/Scandalous.Avalonia.csproj \
-c Release -r osx-x64 --self-contained true -o publish/outOCR requires Tesseract language data files:
- Download the required
.traineddatafiles from tessdata_fast. For example, downloadeng.traineddatafor English. - Place the files in a directory such as
C:\tessdataon Windows or~/tessdataon macOS and Linux. - Expand OCR Settings in Scandalous, enable OCR, and choose that directory.
- Select a language found in the directory.
Scandalous uses the selected OCR language during PDF export. If a previous language is available, it is reused; otherwise it prefers
engwhen the file is present and falls back to the first available model in the tessdata folder.
- Launch Scandalous. The application automatically searches for scanners; use Refresh to search again.
- Select an output folder and enter a base filename without an extension.
- Select a scanner.
- Configure the color mode, paper source, document output, DPI, deskew, blank-page exclusion, and OCR settings.
- Select Scan.
- For a flatbed scan in Combined PDF mode, select Yes after each page to scan another page or No to finish.
During scanning, Scandalous saves temporary PNG files in the operating system's temporary directory and displays the most recently scanned page. These temporary files are deleted when the scan finishes.
- Combined output starts with
<base-name>.pdf. - Individual output creates one PDF per page.
- If a filename already exists, Scandalous adds a numeric suffix:
<base-name>_2.pdf,<base-name>_3.pdf, and so on.
After combined output is created, Scandalous attempts to open it in the system's default PDF viewer. Individual PDFs are not opened automatically.
Scandalous.Core.Models.ScanConfiguration contains the persisted scan settings:
OutputFolderOutputBaseFileNameColorModeDocumentOptionsAutoDeskewExcludeBlankPagesScanResolutionDPIScannerPaperSourceOcrEnabledTessdataFolderTessdataLanguageCodeSelectedScannerNameLastKnownScannerUrl
Settings are saved when the main window closes. Window size, position, and state are saved separately.
FolderValidator checks that folder paths are non-empty and rejects invalid path segments, navigation segments (. and ..), trailing spaces or periods, and segments longer than 255 characters. Windows reserved device names such as CON, PRN, and NUL are rejected on Windows.
FileNameValidator checks that base filenames are non-empty, contain no extension separator or platform-invalid filename characters, do not end in a space or period, and are no longer than 255 characters. Windows reserved device names are rejected on Windows. The UI currently limits base filename input to 200 characters.
Scandalous.Avalonia/— Avalonia desktop UI, view model, dialogs, and application entry point.Scandalous.Core/— scanner integration, PDF and OCR services, configuration, models, and validation.Scandalous.Core.Tests/— xUnit tests for the core library.Scandalous.sln— solution containing the Avalonia app, core library, and tests.publish-mac.sh— creates a self-contained macOS application bundle.ThirdPartyNotices.txt— notices for third-party software distributed with the application.
Copyright 2025-2026 Thomas Hernly. Released under the GNU General Public License v3.0.