# PaperScan Een lokale, privacy-bewuste documentscanner voor Android. Scant papieren documenten met de camera, detecteert automatisch de randen, corrigeert het perspectief en bundelt meerdere pagina's in één PDF. Die PDF kun je delen via Android of rechtstreeks uploaden naar je zelf-gehoste **Paperless-ngx**. **Alles gebeurt op het toestel.** Camerabeelden, randdetectie (OpenCV) en PDF-creatie verlaten je telefoon niet. De enige netwerkverbinding is de optionele upload naar de Paperless-server die jij zelf configureert. Er is geen AI of cloud-verwerking. ## Functies - 📷 Camerapreview met multi-page vastleggen (pagina na pagina toevoegen) - ✂️ Automatische randdetectie + perspectiefcorrectie (OpenCV), met handmatige hoekcorrectie - 🎨 Filters per pagina: kleur, grijstinten, zwart-wit (documentmodus) - 🔄 Pagina's draaien, herordenen en verwijderen - 📄 Export naar multi-page PDF (A4 of originele grootte) - ☁️ Directe upload naar Paperless-ngx **of** delen via het Android-deelmenu - 🔐 API-token versleuteld opgeslagen (Android Keystore / EncryptedSharedPreferences) ## Tech Kotlin · Jetpack Compose · CameraX · OpenCV (`org.opencv:opencv` via Maven) · `PdfDocument` · OkHttp · DataStore. minSdk 26 (Android 8), target/compile SDK 35. ## Lokaal bouwen 1. Open het project in **Android Studio** (Ladybug of nieuwer). Dit genereert automatisch de Gradle wrapper (`gradlew` + `gradle-wrapper.jar`). 2. Sluit een toestel aan of start een emulator en druk op **Run**. Of vanaf de command line (na `gradle wrapper` één keer): ```bash ./gradlew assembleDebug # debug-APK, geen signing nodig ./gradlew assembleRelease # release-APK, vereist signing (zie onder) ``` De release-APK verschijnt in `app/build/outputs/apk/release/`. ## Signing key aanmaken Nodig voor release-builds (en dus voor updates die elkaar kunnen overschrijven). ```bash keytool -genkey -v -keystore release.jks -keyalg RSA -keysize 2048 \ -validity 10000 -alias paperscan ``` Bewaar `release.jks` **veilig en buiten git** (staat al in `.gitignore`). Voor lokale release-builds maak je een `keystore.properties` in de projectroot (zie `keystore.properties.example`): ```properties storeFile=/pad/naar/release.jks storePassword=... keyAlias=paperscan keyPassword=... ``` ## Bouwen via Gitea Actions De workflow `.gitea/workflows/build.yml` bouwt een getekende release-APK bij elke versietag (`git tag v0.1.0 && git push --tags`) of via een handmatige run. Zet in je Gitea-repo onder **Settings → Actions → Secrets** deze secrets klaar: | Secret | Inhoud | | --- | --- | | `SIGNING_KEYSTORE_BASE64` | `base64 -w0 release.jks` (de keystore als base64) | | `SIGNING_STORE_PASSWORD` | wachtwoord van de keystore | | `SIGNING_KEY_ALIAS` | bv. `paperscan` | | `SIGNING_KEY_PASSWORD` | wachtwoord van de sleutel | De build gebruikt env-vars, dus er komt niets gevoeligs in de repo terecht. De APK komt als artifact `paperscan-release` beschikbaar bij de workflow-run. > Zorg dat je Gitea Actions-runner Docker-images kan trekken (`mingc/android-build-box`). ## Paperless-ngx instellen (in de app) 1. Maak in Paperless een API-token aan: **Instellingen → profiel → API-token** (of via `/api/token/`). 2. Open in PaperScan het tandwiel → vul **server-URL** (bv. `https://paperless.thuis.lan`) en het **token** in → **Verbinding testen** → **Opslaan**. Gebruik bij voorkeur **https**; bij `http://` waarschuwt de app dat token en documenten onversleuteld over het netwerk gaan. ## Projectstructuur ``` app/src/main/java/eu/geyskens/pdfscan/ ├── PaperScanApp.kt # Application; laadt OpenCV native libs ├── MainActivity.kt # Compose host + navigatie ├── ScanViewModel.kt # scan-sessie, rendering, export, upload ├── data/ # Page-model, ScanFilter, SettingsRepository ├── scan/ # EdgeDetector, ImageProcessor, BitmapIo (OpenCV) ├── pdf/ # PdfBuilder (multi-page PDF) ├── paperless/ # PaperlessClient (OkHttp REST) └── ui/screens/ # Camera, Pages, Crop, Export, Settings ``` ## Roadmap / ideeën - Live randdetectie-overlay tijdens het richten (nu bij vastleggen) - OCR-tekstlaag (bv. Tesseract) volledig on-device - Batch-import van bestaande foto's uit de galerij