Initial commit: PaperScan — lokale Android documentscanner voor Paperless-ngx
Native Kotlin/Compose app met CameraX + OpenCV randdetectie/perspectiefcorrectie, multi-page PDF-export, en Paperless-ngx upload (of Android deelmenu). Alles lokaal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
110
README.md
Normal file
110
README.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user