MCPcopy Index your code
hub / github.com/egdels/makeacopy

github.com/egdels/makeacopy @v4.6.0-paddlev6

Chat with this repo
repository ↗ · DeepWiki ↗ · release v4.6.0-paddlev6 ↗ · + Follow
8,023 symbols 25,694 edges 529 files 1,947 documented · 24%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

MakeACopy

MakeACopy is an open-source offline document scanner with OCR for Android, designed for privacy-friendly and self-hosted document workflows.

It allows you to digitize paper documents into searchable PDFs while keeping the entire processing pipeline on your device. The app works completely offline and avoids any cloud services, telemetry, or tracking.

MakeACopy is designed to be a reliable building block for privacy-friendly document workflows, especially when combined with self-hosted storage systems.

Looking for a Microsoft Lens alternative?

With the discontinuation of Microsoft Lens, many users are looking for a reliable way to scan documents on Android.

MakeACopy offers the same core building blocks — document scanning, OCR, and searchable PDF export — while following a fundamentally different design:

  • Fully offline – no cloud services required
  • No tracking or telemetry
  • Open source and auditable
  • Designed for long-term, self-hosted workflows

Instead of integrating into a cloud ecosystem, MakeACopy focuses on local processing and interoperability with tools like SambaLite, paperless-ngx, and Syncthing.

This makes it especially suitable for users who prefer control, privacy, and predictable behavior over cloud-based convenience features.

Mobile Document Pipeline

MakeACopy can be combined with SambaLite to create a fully automated mobile document workflow:

Paper document
      ↓
Scan with MakeACopy
      ↓
Inbox folder
      ↓
SambaLite folder sync
      ↓
NAS / archive (e.g. paperless-ngx)

This setup effectively turns your smartphone into a privacy-friendly mobile network scanner for self-hosted document archives.

Design Philosophy

MakeACopy treats privacy and offline operation as technical design decisions, not as moral or political statements. The app works fully offline, is open source, and avoids tracking or cloud services because this results in a simpler, more robust, and more auditable system. Users are encouraged to evaluate MakeACopy based on its concrete features and implementation rather than on positioning or narratives.

App Size Note

To ensure fully offline operation, MakeACopy bundles OCR language models, fonts, and image processing components locally. This significantly increases the app size, but avoids any cloud dependencies or on-demand downloads.

100 MB are not a sign of excess, but of consistency.

Editions and Flavors

MakeACopy is available in two editions (controlled via the Gradle property edition):

Edition OCR Languages Fonts APK Size (arm64-v8a)
Full 23 languages (incl. CJK, Arabic, Hindi, Thai, Turkish) 5 fonts (incl. CJK, Devanagari) ~99 MB
Light English + German 1 font (NotoSans) ~58 MB

Both editions include the same ML-based document detection (ONNX model), OpenCV image processing, and full offline functionality. Both editions use an operator-stripped ONNX Runtime build that includes only the operators required for document detection. The Light edition additionally ships fewer OCR language models and fonts, and uses a minimal ONNX Runtime AAR without XNNPACK and NNAPI to further reduce APK size.

In addition, MakeACopy is built in two product flavors (ocr flavor dimension):

Flavor OCR Backend Notes
paddle PaddleOCR V5 Published flavor for F-Droid and Google Play. Uses PaddleOCR only, without Tesseract runtime, Tesseract language data, or OCR dictionaries.
standard Tesseract only Legacy flavor for existing Tesseract language data and workflows. Available via GitHub Releases. No PaddleOCR assets bundled.

The Full + paddle combination is what is published on F-Droid and Google Play. The standard Tesseract flavor and the Light edition are available via GitHub Releases.

Get it on F-Droid Get it on Google Play

Downloads last month Downloads all time

Or download the latest APK from the Releases Section.

License

APK Verification

All official releases of MakeACopy are signed with one of the following certificates:

  • Upload key (used for GitHub releases, F-Droid, and sideload APKs)
    SHA-256: AE:32:2D:3F:B7:1A:FE:21:DF:47:27:E3:7A:5C:68:03:51:1D:5A:2F:E1:FC:31:35:43:0C:EE:06:99:FA:1B:34

  • Google Play App Signing key (used for Play Store releases)
    SHA-256: C0:71:44:39:CB:51:62:32:A4:47:91:7A:6F:C2:28:1E:45:FA:AA:DD:37:F8:30:B1:01:1F:B4:85:68:8E:0D:64

Verify with apksigner

apksigner verify --print-certs MakeACopy-vX.Y.Z.apk

Features

  • Camera Scanning: Capture documents using the device camera
  • Edge Detection: Automatic document edge detection using OpenCV, enhanced with a custom-trained machine learning model (ONNX, Apache 2.0)
  • Perspective Correction: Adjust and crop documents with manual or automatic perspective correction
  • Image Enhancement: Apply filters (grayscale, contrast, sharpening)
  • OCR: Offline text recognition with PaddleOCR in the published paddle flavor
  • OCR Review: Interactive review and correction of OCR results with word-level editing, dictionary-based suggestions, confidence highlighting, and re-OCR for individual words
  • PDF Export: Save as searchable PDF with recognized text
  • JPEG Export: Export scans as high-quality JPEG images (configurable quality, color/BW)
  • Multi-page Scanning: Combine multiple pages into one document; reorder and manage pages before export
  • Last Scans: Quickly access and reuse your most recent scans
  • Inbox Mode: Automatically save scans to a predefined folder — ideal for paperless-ngx, Nextcloud, or Syncthing workflows
  • Share & Save: Export locally or share with other apps
  • Dark Mode: Material 3 theme with day/night support
  • Privacy-Focused: 100% offline functionality, no internet connection required

Accessibility Mode

Inbox Mode

OCR Languages

MakeACopy supports fully offline OCR. The published paddle flavor uses PaddleOCR; choose the closest script or language group in the OCR language selector during the OCR step.

Supported out of the box: - English (English) - German (Latin), French (Latin), Italian (Latin), Spanish (Latin), Portuguese (Latin), Dutch (Latin), Polish (Latin), Czech (Latin), Slovak (Latin), Hungarian (Latin), Romanian (Latin), Danish (Latin), Norwegian (Latin), Swedish (Latin), Turkish (Latin) - Chinese (Simplified) (Chinese), Chinese (Traditional) (Chinese) - Russian (East Slavic), Thai (Thai) - Arabic (Arabic), Persian/Farsi (Arabic) - Hindi (Devanagari) - Greek (Greek)

In the paddle flavor, select the visible OCR language group for your document:

Document language Choose in the OCR language selector
English English
German, French, Italian, Spanish, Portuguese, Dutch, Polish, Czech, Slovak, Hungarian, Romanian, Danish, Norwegian, Swedish, Turkish Latin
Chinese Simplified or Traditional Chinese
Russian East Slavic
Thai Thai
Arabic and Persian/Farsi Arabic
Hindi Devanagari
Greek Greek

The F-Droid and Google Play links point to the paddle flavor. Use GitHub Releases if you need the standard Tesseract flavor.

Notes: - All OCR runs fully offline on-device. - For Chinese, MakeACopy includes appropriate CJK fonts for better PDF text embedding. - For Arabic and Persian, MakeACopy includes the Noto Naskh Arabic font for proper RTL (right-to-left) text rendering in PDF exports. - For Hindi, MakeACopy includes the Noto Sans Devanagari font for proper Devanagari text rendering in PDF exports.

Screenshots

MakeACopy screenshot 1 MakeACopy screenshot 2 MakeACopy screenshot 3 MakeACopy screenshot 4

Installation

F-Droid

MakeACopy is F-Droid compliant. The F-Droid listing provides the paddle flavor. The app builds all required native components from source during CI/local builds:

  1. OpenCV Java Classes: The required OpenCV Java wrapper classes are directly included in the app's source tree (copied from OpenCV but now part of this project). They are no longer used from the submodule.
  2. OpenCV Native Libraries: All OpenCV native libraries are built from source using the official OpenCV code provided via the Git submodule at external/opencv.
  3. ONNX Runtime Native Libraries: For ML-assisted edge detection, ONNX Runtime is built from source (XNNPACK and NNAPI, Java bindings) using the submodule at external/onnxruntime via scripts/build_onnxruntime_android.sh. The resulting artifacts are integrated into app/src/main/jniLibs/<ABI>/ (e.g., libonnxruntime.so, libonnxruntime4j_jni.so) and app/libs/ (onnxruntime-*.jar).

This approach ensures F-Droid compatibility by not including any pre-compiled binaries in the repository and building OpenCV and ONNX Runtime native components from source.

GitHub Releases

You can download the latest APKs from the Releases page. Use GitHub Releases if you need the standard Tesseract flavor or the Light edition.

Automated Builds

All automated builds are handled by a single GitHub Actions workflow:

The workflow contains two parallel jobs:

Full build (build): - Sets up JDK 21 (Temurin) and installs Android NDK 28.0.13004108 - Pins CMake 3.31.6 and Python 3.11.2 for deterministic native builds - Checks out submodules (external/opencv and external/onnxruntime) - Builds OpenCV native libraries from source via scripts/build_opencv_android.sh - Collects reproducibility evidence for native builds (scripts/collect_repro_evidence.sh) - Integrates OpenCV artifacts into the app via scripts/prepare_opencv.sh - Builds ONNX Runtime for Android (XNNPACK and NNAPI, Java bindings) via scripts/build_onnxruntime_android.sh — the operator config supports DocQuad corner detection and PaddleOCR V5 - Builds the Full edition Android app with Gradle for both flavors (paddle and standard), producing the published Paddle artifacts and the Tesseract legacy artifacts - Verifies that no test data leaks into release APKs via :app:verifyNoTestDataInApk - Renames artifacts to MakeACopy-vX.Y.Z-<abi>-release.apk (standard) and MakeACopy-vX.Y.Z-<abi>-paddle-release.apk (paddle), plus release AABs

Light build (build-light): - Depends on the Full build job and downloads the native libraries (jniLibs and JARs) built from source - Sets up JDK 21 only (no native build scripts needed) - Builds the Light edition for the standard flavor only: ./gradlew :app:assembleStandardRelease -Pedition=light (PaddleOCR is not part of the Light edition) - Produces per-ABI APKs named MakeACopy-Light-vX.Y.Z-<abi>-release.apk

Behavior by event type: - Push/PR to main (non-tag): - Builds unsigned artifacts (Full: Release AAB and per-ABI Release APKs; Light: per-ABI Release APKs) - Uploads all artifacts for download from the workflow run - Tag (refs/tags/vX.Y.Z): - Optionally decodes a keystore from repository secrets and signs the builds - Verifies APK signatures using apksigner - Renames artifacts to MakeACopy-vX.Y.Z-<abi>-release.apk (standard), MakeACopy-vX.Y.Z-<abi>-paddle-release.apk (paddle), MakeACopy-Light-vX.Y.Z-<abi>-release.apk, plus release AABs - Generates SHA-256 c

Extension points exported contracts — how you extend this code

OcrEngine (Interface)
The OcrEngine interface defines the contract for Optical Character Recognition (OCR) engines that can extract text from [6 …
app/src/main/java/de/schliweb/makeacopy/utils/ocr/OcrEngine.java
CornerDetector (Interface)
Schlanke Abstraktion für Corner-Detection. Implementierungen dürfen niemals Exceptions nach außen werfen, sondern mü [13 …
app/src/main/java/de/schliweb/makeacopy/ml/corners/CornerDetector.java
Atable (Interface)
(no doc) [7 implementers]
app/src/main/java/org/opencv/core/Mat.java
CollectionsRepository (Interface)
Interface for managing collections of scans within the application. Provides methods to create, retrieve, modify, and de [2 …
app/src/main/java/de/schliweb/makeacopy/data/library/CollectionsRepository.java
ScansRepository (Interface)
Repository interface for managing and retrieving scan data. This interface provides methods to interact with scan entiti [2 …
app/src/main/java/de/schliweb/makeacopy/data/library/ScansRepository.java

Core symbols most depended-on inside this repo

throwJavaException
called by 862
external/opencv_pinned_jni/imgproc.inl.hpp
size
called by 803
app/src/main/java/org/opencv/core/Mat.java
max
called by 790
app/src/main/java/org/opencv/core/Core.java
get
called by 769
app/src/main/java/org/opencv/core/Mat.java
throwJavaException
called by 528
external/opencv_pinned_jni/video.inl.hpp
isEmpty
called by 509
app/src/main/java/de/schliweb/makeacopy/data/library/OcrTextExtractor.java
throwJavaException
called by 466
external/opencv_pinned_jni/core.inl.hpp
add
called by 316
app/src/main/java/org/opencv/core/Core.java

Shape

Method 5,767
Function 1,577
Class 611
Interface 35
Enum 33

Languages

Java79%
C++15%
Python5%
Kotlin1%

Modules by API surface

external/opencv_pinned_jni/imgproc.inl.hpp440 symbols
app/src/main/java/org/opencv/imgproc/Imgproc.java426 symbols
app/src/main/java/org/opencv/core/Core.java347 symbols
external/opencv_pinned_jni/video.inl.hpp286 symbols
external/opencv_pinned_jni/core.inl.hpp237 symbols
app/src/main/java/org/opencv/core/Mat.java202 symbols
external/opencv_pinned_jni/photo.inl.hpp157 symbols
app/src/main/java/de/schliweb/makeacopy/ui/camera/CameraFragment.java105 symbols
app/src/main/java/de/schliweb/makeacopy/ui/crop/TrapezoidSelectionView.java96 symbols
app/src/main/java/org/opencv/photo/Photo.java73 symbols
training/scripts/evaluate_docquad_models.py69 symbols
app/src/main/java/de/schliweb/makeacopy/utils/image/OpenCVUtils.java68 symbols

For agents

$ claude mcp add makeacopy \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page