adb-mlkit 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. adb_mlkit-0.1.0/CONTRIBUTING.md +49 -0
  2. adb_mlkit-0.1.0/LICENSE +21 -0
  3. adb_mlkit-0.1.0/MANIFEST.in +6 -0
  4. adb_mlkit-0.1.0/PKG-INFO +161 -0
  5. adb_mlkit-0.1.0/README.md +137 -0
  6. adb_mlkit-0.1.0/README.vi.md +98 -0
  7. adb_mlkit-0.1.0/SECURITY.md +23 -0
  8. adb_mlkit-0.1.0/THIRD_PARTY_NOTICES.md +11 -0
  9. adb_mlkit-0.1.0/docs/API.md +88 -0
  10. adb_mlkit-0.1.0/docs/PROTOCOL.md +79 -0
  11. adb_mlkit-0.1.0/docs/PUBLISHING.md +67 -0
  12. adb_mlkit-0.1.0/docs/VERIFICATION.md +32 -0
  13. adb_mlkit-0.1.0/examples/read_images.py +12 -0
  14. adb_mlkit-0.1.0/examples/xpath_region.py +13 -0
  15. adb_mlkit-0.1.0/pyproject.toml +33 -0
  16. adb_mlkit-0.1.0/scripts/prepare_package.py +53 -0
  17. adb_mlkit-0.1.0/scripts/smoke_install.py +28 -0
  18. adb_mlkit-0.1.0/scripts/verify_wheel.py +26 -0
  19. adb_mlkit-0.1.0/setup.cfg +4 -0
  20. adb_mlkit-0.1.0/src/adb_mlkit/__init__.py +8 -0
  21. adb_mlkit-0.1.0/src/adb_mlkit/__main__.py +3 -0
  22. adb_mlkit-0.1.0/src/adb_mlkit/assets/adb-mlkit.apk +0 -0
  23. adb_mlkit-0.1.0/src/adb_mlkit/assets/helper.json +5 -0
  24. adb_mlkit-0.1.0/src/adb_mlkit/cli.py +96 -0
  25. adb_mlkit-0.1.0/src/adb_mlkit/client.py +244 -0
  26. adb_mlkit-0.1.0/src/adb_mlkit/helper.py +36 -0
  27. adb_mlkit-0.1.0/src/adb_mlkit/models.py +100 -0
  28. adb_mlkit-0.1.0/src/adb_mlkit.egg-info/PKG-INFO +161 -0
  29. adb_mlkit-0.1.0/src/adb_mlkit.egg-info/SOURCES.txt +33 -0
  30. adb_mlkit-0.1.0/src/adb_mlkit.egg-info/dependency_links.txt +1 -0
  31. adb_mlkit-0.1.0/src/adb_mlkit.egg-info/entry_points.txt +2 -0
  32. adb_mlkit-0.1.0/src/adb_mlkit.egg-info/requires.txt +8 -0
  33. adb_mlkit-0.1.0/src/adb_mlkit.egg-info/top_level.txt +1 -0
  34. adb_mlkit-0.1.0/tests/test_packaging.py +98 -0
  35. adb_mlkit-0.1.0/tests/test_sdk.py +289 -0
@@ -0,0 +1,49 @@
1
+ # Contributing and publishing
2
+
3
+ ## Local checks
4
+
5
+ ```text
6
+ python -m pip install -e ".[dev]"
7
+ python -m unittest discover -s tests -v
8
+ # After building Android:
9
+ python scripts/prepare_package.py
10
+ python -m build
11
+ python scripts/smoke_install.py dist/adb_mlkit-0.1.0-py3-none-any.whl
12
+ ```
13
+
14
+ Android checks (from `android/`; use `gradlew.bat` on Windows):
15
+
16
+ ```text
17
+ ./gradlew :app:testDebugUnitTest :app:lintDebug :app:assembleDebug
18
+ ```
19
+
20
+ Use the toolchain in `android/README.md`. Do not commit `local.properties`, signing keys, APK binaries, `.venv`, caches, private images or result files. Keep Gradle wrapper files in source control, including `gradle-wrapper.jar`.
21
+
22
+ ## Device smoke test
23
+
24
+ The unit suite and a successful APK build do not prove device behavior. Use an authorized test device and a **synthetic non-sensitive image** for integration checks:
25
+
26
+ 1. Build and package the helper. On an authorized test device without the helper, run `adb-mlkit recognize --file synthetic.png` and verify automatic installation followed by OCR. Repeat recognition and verify that it does not reinstall. Use `adb-mlkit install ...` when explicitly testing updates or a custom APK.
27
+ 2. Use `adb-mlkit info` to verify device/helper setup.
28
+ 3. Recognize the same synthetic image with `--file` and `--device-file` after manually copying it to a readable shared folder. Compare text, dimensions, ROI and rotated geometry.
29
+ 4. Use a screen containing synthetic text for `--screenshot`; use optional `[ui]` dependencies for XPath.
30
+ 5. Test each script with corresponding synthetic text. Record device model/API, source image resolution and first/warm/end-to-end timing separately.
31
+ 6. Include invalid-image, out-of-bounds ROI, permission-denied, disconnected-device and multiple-device tests. Verify error messages and request cleanup.
32
+
33
+ Never use production bank/customer images in CI or public issues. Do not infer multilingual accuracy from a single Latin image.
34
+
35
+ ## API changes
36
+
37
+ Update Python result models, Android serialization, protocol documentation and tests together. Incompatible wire-format changes require a new schema version. Do not change coordinate semantics silently. Preserve error codes and avoid fabricating confidence values.
38
+
39
+ ## Publishing this repository
40
+
41
+ The project is prepared locally; nothing is automatically pushed or published. Review all files and the license before creating a remote. Replace example paths/serials only in your local commands, not with real private data in documentation.
42
+
43
+ The configured repository is https://github.com/zidonghua-source/ADB-MLKit. Commit and push only after reviewing `git status` and `git diff --cached`. Forks should update the project URLs and Trusted Publisher configuration for their own repository.
44
+
45
+ GitHub Actions run tests/builds and produce artifacts. A separate **manual-only** PyPI/TestPyPI workflow is documented in [PUBLISHING.md](docs/PUBLISHING.md); configure protected environments and Trusted Publishing before using it. Nothing publishes automatically on push. Review permissions and current third-party dependency terms before distributing an APK. Debug signing on CI is ephemeral, so a CI APK may not update a locally signed installation without a signature conflict; use one controlled signing key for stable releases and never commit it. Do not uninstall an existing helper blindly to resolve a conflict if it contains data you need.
46
+
47
+ ## Scope
48
+
49
+ ADB-MLKit is an OCR SDK/CLI and helper, not a general phone automation framework. Additional features should preserve offline execution, explicit device selection and least privilege. HTTP services, persistent Android daemons and cross-process request queues require separate threat-model and protocol design.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ADB-MLKit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ include README.md README.vi.md LICENSE THIRD_PARTY_NOTICES.md SECURITY.md CONTRIBUTING.md
2
+ recursive-include docs *.md
3
+ recursive-include examples *.py
4
+ recursive-include tests *.py
5
+ recursive-include scripts *.py
6
+ recursive-include src/adb_mlkit/assets *.apk *.json
@@ -0,0 +1,161 @@
1
+ Metadata-Version: 2.4
2
+ Name: adb-mlkit
3
+ Version: 0.1.0
4
+ Summary: On-device multilingual ML Kit OCR from Python over ADB
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/zidonghua-source/ADB-MLKit
7
+ Project-URL: Repository, https://github.com/zidonghua-source/ADB-MLKit
8
+ Project-URL: Issues, https://github.com/zidonghua-source/ADB-MLKit/issues
9
+ Project-URL: Documentation, https://github.com/zidonghua-source/ADB-MLKit/blob/main/README.md
10
+ Keywords: adb,android,ocr,mlkit,vietnamese
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ License-File: THIRD_PARTY_NOTICES.md
17
+ Provides-Extra: ui
18
+ Requires-Dist: uiautomator2<4,>=3.0; extra == "ui"
19
+ Requires-Dist: Pillow>=10; extra == "ui"
20
+ Provides-Extra: dev
21
+ Requires-Dist: build>=1.2; extra == "dev"
22
+ Requires-Dist: twine>=6; extra == "dev"
23
+ Dynamic: license-file
24
+
25
+ # ADB-MLKit
26
+
27
+ **Read text on Android from Python, using Google's on-device ML Kit models over ADB.**
28
+
29
+ ADB-MLKit consists of a Python SDK/CLI and a small, headless Android instrumentation helper. It is an independent community project, not an official Google product. No OCR cloud account or API key is required.
30
+
31
+ [Tiếng Việt](README.vi.md) · [API reference](docs/API.md) · [Protocol](docs/PROTOCOL.md) · [Security](SECURITY.md)
32
+
33
+ ## Features
34
+
35
+ - Read a local image, encoded image bytes, an image already on Android, or a screenshot.
36
+ - Optional XPath-to-region lookup with uiautomator2; recognized text always comes from OCR.
37
+ - Five bundled script models: **Latin (including Vietnamese), Chinese, Japanese, Korean and Devanagari**.
38
+ - Crop ROI, clockwise rotation, block/line/element text and geometry, engine-provided confidence where available.
39
+ - Multiple devices via explicit serial selection; sequential batch images.
40
+ - Cold/first invocation and repeated-same-image OCR timings, plus host transfer/startup/cleanup timings.
41
+ - Request-isolated temporary storage and best-effort cleanup; Base64-safe ADB input transport.
42
+ - Structured JSON output, typed Python results, unit tests and GitHub Actions build configuration.
43
+
44
+ ## Requirements
45
+
46
+ - Python 3.10+, Android platform-tools (`adb`) on PATH, and an authorized USB/TCP device.
47
+ - Android 6.0 / API 23 or newer.
48
+ - A distribution wheel includes the version-matched Android helper APK. End users do not need Java/Gradle/Android Studio.
49
+ - ADB/platform-tools remains a separate prerequisite; pip never installs an APK on your phone automatically.
50
+ - Optional XPath support: install the `[ui]` extra.
51
+
52
+ This does **not** bypass Android screen-capture restrictions or private-storage permissions. Avoid enabling ADB on untrusted networks.
53
+
54
+ ## Quick start
55
+
56
+ Install the built wheel (available locally in `dist/`; publication is a separate maintainer step):
57
+
58
+ ```powershell
59
+ python -m pip install ./dist/adb_mlkit-0.1.0-py3-none-any.whl
60
+ adb-mlkit devices
61
+ ```
62
+
63
+ After the maintainer publishes this project to PyPI, installation by name becomes:
64
+
65
+ ```text
66
+ python -m pip install adb-mlkit
67
+ python -m pip install "adb-mlkit[ui]"
68
+ ```
69
+
70
+ These package-index commands require an actual release; preparing this repository does not publish one. See [PyPI publishing](docs/PUBLISHING.md).
71
+
72
+ Run OCR directly. Recognition commands and Python recognition methods automatically install the bundled, checksum-verified helper on the selected phone if it is missing:
73
+
74
+ ```powershell
75
+ adb-mlkit recognize --screenshot --language vi --runs 3 --json
76
+ adb-mlkit info
77
+ ```
78
+
79
+ An existing helper is not automatically reinstalled or updated. Use `adb-mlkit install` to install/update it manually, or `adb-mlkit install path/to/custom.apk` for a custom APK. Installation errors stop recognition; the SDK never uninstalls an existing package to resolve a conflict.
80
+
81
+ The new helper package is **`io.github.adbmlkit.helper`**, separate from the earlier `com.example.mlkitocrtest` prototype. The prototype APK cannot serve this protocol.
82
+
83
+ ### Images on Android
84
+
85
+ ```powershell
86
+ adb-mlkit recognize --device-file "/sdcard/Download/example.png" --language vi --json
87
+ ```
88
+
89
+ The Android shell must already be allowed to read the path. The host reads the encoded bytes over ADB and stages them in helper-private storage; this is not zero-copy device-only ingestion and does not require broad storage permissions.
90
+
91
+ ### Local images, crop and other scripts
92
+
93
+ ```powershell
94
+ adb-mlkit recognize --file image.png --language vi --roi 60 100 1000 700 --runs 5
95
+ adb-mlkit recognize --file japanese.png --script japanese --json
96
+ adb-mlkit recognize --file rotated.jpg --rotation 90 --json --output result.json
97
+ adb-mlkit batch first.png second.png --language vi --json --output batch.json
98
+ adb-mlkit --serial DEVICE_SERIAL recognize --screenshot --script latin
99
+ ```
100
+
101
+ Existing output files are protected unless `--overwrite` is given. Global options (`--serial`, `--adb-path`, `--timeout`) go **before** the subcommand. `python -m adb_mlkit` is equivalent to `adb-mlkit`.
102
+
103
+ ### Python API
104
+
105
+ ```python
106
+ from adb_mlkit import ADBMLKit
107
+
108
+ ocr = ADBMLKit(serial="DEVICE_SERIAL")
109
+ result = ocr.recognize_device_file("/sdcard/Download/example.png", language="vi", runs=3)
110
+ print(result.text)
111
+ print(result.timing) # Android decode/init/recognition durations
112
+ print(result.host_timing) # Host load/setup/transfer/instrumentation/result/cleanup/total
113
+
114
+ for block in result.blocks:
115
+ for line in block.lines:
116
+ print(line.text, line.bounds, line.confidence)
117
+ ```
118
+
119
+ See [API reference](docs/API.md) and [examples](examples/) for all entry points.
120
+
121
+ ## Languages versus scripts
122
+
123
+ `--language vi` selects the **Latin model**, not a Vietnamese-only model. It does not translate, force output into Vietnamese, or provide a recognition hint. The SDK maps a documented set of aliases to the five supported scripts; `adb-mlkit languages` lists them. The alias list is not Google's exhaustive language list. Unsupported scripts (for example Arabic or Thai) are not automatically recognized by this integration.
124
+
125
+ ML Kit may recognize mixed-script text supported by a selected model, but this project does not run all five recognizers automatically or promise arbitrary multilingual detection. For mixed documents, select and benchmark an appropriate model or process the image separately with multiple models.
126
+
127
+ ## Coordinate and timing semantics
128
+
129
+ ROI is `[left, top, right, bottom]` in the original unrotated source image, with exclusive right/bottom edges. Crop precedes rotation. Output geometry uses the cropped, rotated image coordinate system, **not necessarily screen coordinates**. Explicit rotation is used; normalize EXIF orientation yourself when needed.
130
+
131
+ `runs=N` recognizes **one image N times** using one recognizer in one invocation. The first run can include lazy model initialization; later values measure warm recognition. Each API call starts instrumentation again. Warm OCR time is not end-to-end latency. The host total includes image loading/capture, helper setup, transfers and cleanup. `host_timing.setup_ms` measures the package check and any automatic APK installation; the first call on a device without the helper therefore takes longer. No fixed speed or accuracy guarantee is made.
132
+
133
+ ## Development and verification
134
+
135
+ ```powershell
136
+ python -m pip install -e ".[dev]"
137
+ python -m unittest discover -s tests -v
138
+ # Build Android first: see android/README.md
139
+ python scripts/prepare_package.py
140
+ python -m build
141
+ python scripts/verify_wheel.py dist/adb_mlkit-0.1.0-py3-none-any.whl
142
+ ```
143
+
144
+ Python unit tests mock ADB; they do not establish on-device accuracy. Build the Android helper separately. See [CONTRIBUTING.md](CONTRIBUTING.md) for synthetic-image device tests and publication notes. No device credentials or private images are included.
145
+
146
+ ## Limitations
147
+
148
+ - One instrumentation invocation at a time per device. Use one client per device; separate processes must coordinate themselves.
149
+ - No always-running HTTP daemon, streaming camera service, translation API or cloud fallback.
150
+ - Image input limit: 32 MiB; decoded dimensions: at most 32 million pixels. Large input can still be memory-intensive.
151
+ - Same-device screenshot and XPath lookup are sequential, not an atomic UI snapshot. Changing UI may move the target.
152
+ - Debug APK is a developer tool, not a hardened Play Store app. Model libraries make the all-script APK substantially larger than a Latin-only helper.
153
+ - ML Kit models/libraries have their own terms. This repository provides integration source, not source code for Google's recognition models.
154
+
155
+ ## License and upstream
156
+
157
+ Project code: [MIT](LICENSE). See [third-party notices](THIRD_PARTY_NOTICES.md).
158
+
159
+ - [Google ML Kit Android setup](https://developers.google.com/ml-kit/vision/text-recognition/v2/android)
160
+ - [Supported languages](https://developers.google.com/ml-kit/vision/text-recognition/v2/languages)
161
+ - [Official sample source](https://github.com/googlesamples/mlkit)
@@ -0,0 +1,137 @@
1
+ # ADB-MLKit
2
+
3
+ **Read text on Android from Python, using Google's on-device ML Kit models over ADB.**
4
+
5
+ ADB-MLKit consists of a Python SDK/CLI and a small, headless Android instrumentation helper. It is an independent community project, not an official Google product. No OCR cloud account or API key is required.
6
+
7
+ [Tiếng Việt](README.vi.md) · [API reference](docs/API.md) · [Protocol](docs/PROTOCOL.md) · [Security](SECURITY.md)
8
+
9
+ ## Features
10
+
11
+ - Read a local image, encoded image bytes, an image already on Android, or a screenshot.
12
+ - Optional XPath-to-region lookup with uiautomator2; recognized text always comes from OCR.
13
+ - Five bundled script models: **Latin (including Vietnamese), Chinese, Japanese, Korean and Devanagari**.
14
+ - Crop ROI, clockwise rotation, block/line/element text and geometry, engine-provided confidence where available.
15
+ - Multiple devices via explicit serial selection; sequential batch images.
16
+ - Cold/first invocation and repeated-same-image OCR timings, plus host transfer/startup/cleanup timings.
17
+ - Request-isolated temporary storage and best-effort cleanup; Base64-safe ADB input transport.
18
+ - Structured JSON output, typed Python results, unit tests and GitHub Actions build configuration.
19
+
20
+ ## Requirements
21
+
22
+ - Python 3.10+, Android platform-tools (`adb`) on PATH, and an authorized USB/TCP device.
23
+ - Android 6.0 / API 23 or newer.
24
+ - A distribution wheel includes the version-matched Android helper APK. End users do not need Java/Gradle/Android Studio.
25
+ - ADB/platform-tools remains a separate prerequisite; pip never installs an APK on your phone automatically.
26
+ - Optional XPath support: install the `[ui]` extra.
27
+
28
+ This does **not** bypass Android screen-capture restrictions or private-storage permissions. Avoid enabling ADB on untrusted networks.
29
+
30
+ ## Quick start
31
+
32
+ Install the built wheel (available locally in `dist/`; publication is a separate maintainer step):
33
+
34
+ ```powershell
35
+ python -m pip install ./dist/adb_mlkit-0.1.0-py3-none-any.whl
36
+ adb-mlkit devices
37
+ ```
38
+
39
+ After the maintainer publishes this project to PyPI, installation by name becomes:
40
+
41
+ ```text
42
+ python -m pip install adb-mlkit
43
+ python -m pip install "adb-mlkit[ui]"
44
+ ```
45
+
46
+ These package-index commands require an actual release; preparing this repository does not publish one. See [PyPI publishing](docs/PUBLISHING.md).
47
+
48
+ Run OCR directly. Recognition commands and Python recognition methods automatically install the bundled, checksum-verified helper on the selected phone if it is missing:
49
+
50
+ ```powershell
51
+ adb-mlkit recognize --screenshot --language vi --runs 3 --json
52
+ adb-mlkit info
53
+ ```
54
+
55
+ An existing helper is not automatically reinstalled or updated. Use `adb-mlkit install` to install/update it manually, or `adb-mlkit install path/to/custom.apk` for a custom APK. Installation errors stop recognition; the SDK never uninstalls an existing package to resolve a conflict.
56
+
57
+ The new helper package is **`io.github.adbmlkit.helper`**, separate from the earlier `com.example.mlkitocrtest` prototype. The prototype APK cannot serve this protocol.
58
+
59
+ ### Images on Android
60
+
61
+ ```powershell
62
+ adb-mlkit recognize --device-file "/sdcard/Download/example.png" --language vi --json
63
+ ```
64
+
65
+ The Android shell must already be allowed to read the path. The host reads the encoded bytes over ADB and stages them in helper-private storage; this is not zero-copy device-only ingestion and does not require broad storage permissions.
66
+
67
+ ### Local images, crop and other scripts
68
+
69
+ ```powershell
70
+ adb-mlkit recognize --file image.png --language vi --roi 60 100 1000 700 --runs 5
71
+ adb-mlkit recognize --file japanese.png --script japanese --json
72
+ adb-mlkit recognize --file rotated.jpg --rotation 90 --json --output result.json
73
+ adb-mlkit batch first.png second.png --language vi --json --output batch.json
74
+ adb-mlkit --serial DEVICE_SERIAL recognize --screenshot --script latin
75
+ ```
76
+
77
+ Existing output files are protected unless `--overwrite` is given. Global options (`--serial`, `--adb-path`, `--timeout`) go **before** the subcommand. `python -m adb_mlkit` is equivalent to `adb-mlkit`.
78
+
79
+ ### Python API
80
+
81
+ ```python
82
+ from adb_mlkit import ADBMLKit
83
+
84
+ ocr = ADBMLKit(serial="DEVICE_SERIAL")
85
+ result = ocr.recognize_device_file("/sdcard/Download/example.png", language="vi", runs=3)
86
+ print(result.text)
87
+ print(result.timing) # Android decode/init/recognition durations
88
+ print(result.host_timing) # Host load/setup/transfer/instrumentation/result/cleanup/total
89
+
90
+ for block in result.blocks:
91
+ for line in block.lines:
92
+ print(line.text, line.bounds, line.confidence)
93
+ ```
94
+
95
+ See [API reference](docs/API.md) and [examples](examples/) for all entry points.
96
+
97
+ ## Languages versus scripts
98
+
99
+ `--language vi` selects the **Latin model**, not a Vietnamese-only model. It does not translate, force output into Vietnamese, or provide a recognition hint. The SDK maps a documented set of aliases to the five supported scripts; `adb-mlkit languages` lists them. The alias list is not Google's exhaustive language list. Unsupported scripts (for example Arabic or Thai) are not automatically recognized by this integration.
100
+
101
+ ML Kit may recognize mixed-script text supported by a selected model, but this project does not run all five recognizers automatically or promise arbitrary multilingual detection. For mixed documents, select and benchmark an appropriate model or process the image separately with multiple models.
102
+
103
+ ## Coordinate and timing semantics
104
+
105
+ ROI is `[left, top, right, bottom]` in the original unrotated source image, with exclusive right/bottom edges. Crop precedes rotation. Output geometry uses the cropped, rotated image coordinate system, **not necessarily screen coordinates**. Explicit rotation is used; normalize EXIF orientation yourself when needed.
106
+
107
+ `runs=N` recognizes **one image N times** using one recognizer in one invocation. The first run can include lazy model initialization; later values measure warm recognition. Each API call starts instrumentation again. Warm OCR time is not end-to-end latency. The host total includes image loading/capture, helper setup, transfers and cleanup. `host_timing.setup_ms` measures the package check and any automatic APK installation; the first call on a device without the helper therefore takes longer. No fixed speed or accuracy guarantee is made.
108
+
109
+ ## Development and verification
110
+
111
+ ```powershell
112
+ python -m pip install -e ".[dev]"
113
+ python -m unittest discover -s tests -v
114
+ # Build Android first: see android/README.md
115
+ python scripts/prepare_package.py
116
+ python -m build
117
+ python scripts/verify_wheel.py dist/adb_mlkit-0.1.0-py3-none-any.whl
118
+ ```
119
+
120
+ Python unit tests mock ADB; they do not establish on-device accuracy. Build the Android helper separately. See [CONTRIBUTING.md](CONTRIBUTING.md) for synthetic-image device tests and publication notes. No device credentials or private images are included.
121
+
122
+ ## Limitations
123
+
124
+ - One instrumentation invocation at a time per device. Use one client per device; separate processes must coordinate themselves.
125
+ - No always-running HTTP daemon, streaming camera service, translation API or cloud fallback.
126
+ - Image input limit: 32 MiB; decoded dimensions: at most 32 million pixels. Large input can still be memory-intensive.
127
+ - Same-device screenshot and XPath lookup are sequential, not an atomic UI snapshot. Changing UI may move the target.
128
+ - Debug APK is a developer tool, not a hardened Play Store app. Model libraries make the all-script APK substantially larger than a Latin-only helper.
129
+ - ML Kit models/libraries have their own terms. This repository provides integration source, not source code for Google's recognition models.
130
+
131
+ ## License and upstream
132
+
133
+ Project code: [MIT](LICENSE). See [third-party notices](THIRD_PARTY_NOTICES.md).
134
+
135
+ - [Google ML Kit Android setup](https://developers.google.com/ml-kit/vision/text-recognition/v2/android)
136
+ - [Supported languages](https://developers.google.com/ml-kit/vision/text-recognition/v2/languages)
137
+ - [Official sample source](https://github.com/googlesamples/mlkit)
@@ -0,0 +1,98 @@
1
+ # ADB-MLKit — OCR trên Android từ Python
2
+
3
+ Project độc lập gồm **SDK/CLI Python** và **APK Android không có giao diện**, dùng Google ML Kit Text Recognition v2. Đây không phải sản phẩm chính thức của Google.
4
+
5
+ ## Có gì?
6
+
7
+ - Đọc ảnh trên máy tính, bytes ảnh, ảnh có sẵn trong điện thoại và ảnh chụp màn hình.
8
+ - Lấy vùng bằng XPath tùy chọn; XPath chỉ lấy tọa độ, không lấy text từ UI.
9
+ - Năm bộ chữ: Latin (có tiếng Việt), Trung, Nhật, Hàn, Devanagari.
10
+ - Cắt vùng, xoay ảnh, text theo block/dòng/từ, tọa độ và confidence khi engine cung cấp.
11
+ - Đo riêng thời gian OCR và tổng thời gian xử lý; xuất JSON, đọc nhiều ảnh tuần tự.
12
+ - Không gửi ảnh lên cloud; không cần API key hay root.
13
+
14
+ ## Chạy nhanh trên Windows
15
+
16
+ ```powershell
17
+ cd D:\Github\ADB-MLKit
18
+ python -m venv .venv
19
+ .venv\Scripts\Activate.ps1
20
+ python -m pip install .\dist\adb_mlkit-0.1.0-py3-none-any.whl
21
+ ```
22
+
23
+ Wheel đã chứa APK và cả 5 model, không cần tự build Android. ADB/platform-tools vẫn phải cài riêng. Lệnh pip không tự cài app lên điện thoại; khi chạy lệnh đọc văn bản, SDK sẽ tự kiểm tra và cài APK đi kèm đã được xác minh checksum nếu thiết bị chưa có:
24
+
25
+ ```powershell
26
+ adb-mlkit devices
27
+ adb-mlkit recognize --screenshot --language vi --runs 3 --json
28
+ ```
29
+
30
+ Không cần chạy `adb-mlkit install` trước. Cơ chế này áp dụng cho `recognize`, `batch` và các hàm đọc văn bản trong API Python. Nếu APK đã có thì không tự cài lại hay cập nhật. Vẫn có thể dùng `adb-mlkit install` để cài/cập nhật thủ công, hoặc `adb-mlkit install path/to/custom.apk` để chọn APK khác. Nếu cài thất bại, OCR dừng và báo lỗi; SDK không tự gỡ APK hiện có để xử lý xung đột.
31
+
32
+ Sau khi chủ repo phát hành lên PyPI, người dùng sẽ cài bằng `pip install adb-mlkit` hoặc `pip install "adb-mlkit[ui]"`. Hiện việc chuẩn bị source/wheel chưa đồng nghĩa đã đăng lên PyPI. Xem [hướng dẫn phát hành](docs/PUBLISHING.md).
33
+
34
+ Package mới là `io.github.adbmlkit.helper`, không dùng chung APK prototype `com.example.mlkitocrtest`.
35
+
36
+ **Đọc ảnh nằm trong điện thoại:**
37
+
38
+ ```powershell
39
+ adb-mlkit recognize --device-file "/sdcard/Download/anh.png" --language vi --json
40
+ ```
41
+
42
+ ADB phải có quyền đọc đường dẫn đó. Ảnh được đọc về host rồi chuyển vào vùng lưu trữ riêng của APK, không phải xử lý trực tiếp không qua truyền ảnh. Không đọc được thư mục riêng của app khác nếu Android không cho phép.
43
+
44
+ **Đọc ảnh máy tính, Nhật/Hàn/Trung:**
45
+
46
+ ```powershell
47
+ adb-mlkit recognize --file anh.png --language vi
48
+ adb-mlkit recognize --file japanese.png --script japanese --json
49
+ adb-mlkit recognize --file korean.png --script korean --json
50
+ adb-mlkit recognize --file chinese.png --script chinese --json
51
+ ```
52
+
53
+ **Đọc bằng XPath:**
54
+
55
+ ```powershell
56
+ python -m pip install -e ".[ui]"
57
+ adb-mlkit recognize --xpath '//*[@resource-id="com.example:id/dialog"]/..' --language vi --runs 3
58
+ ```
59
+
60
+ Thay XPath bằng phần tử trên app của bạn. Màn hình thay đổi giữa lúc lấy XPath và chụp ảnh có thể làm vùng không còn khớp.
61
+
62
+ ## API Python
63
+
64
+ ```python
65
+ from adb_mlkit import ADBMLKit
66
+
67
+ ocr = ADBMLKit() # Chỉ tự chọn khi có đúng một thiết bị đã được cấp quyền ADB
68
+ result = ocr.recognize_device_file("/sdcard/Download/anh.png", language="vi")
69
+ print(result.text)
70
+ print(result.to_json())
71
+
72
+ result = ocr.recognize_screenshot(roi=(60, 100, 1000, 700), runs=5)
73
+ print(result.timing)
74
+ print(result.host_timing)
75
+ ```
76
+
77
+ Chọn thiết bị cụ thể: `ADBMLKit(serial="SERIAL")` hoặc `adb-mlkit --serial SERIAL recognize ...`.
78
+
79
+ ## Lưu ý quan trọng
80
+
81
+ - `language="vi"` chọn model Latin, không dịch hoặc ép đầu ra thành tiếng Việt. Không hỗ trợ mọi bộ chữ trên thế giới.
82
+ - `runs=5` đọc **cùng một ảnh** 5 lần. Các lần sau đo model đã nạp; tổng thời gian thật còn có chụp ảnh, truyền ADB và khởi chạy APK. `host_timing.setup_ms` đo kiểm tra/cài APK; `total_ms` bao gồm cả bước này nên lần đầu có thể lâu hơn.
83
+ - ROI là tọa độ ảnh gốc trước xoay; kết quả là tọa độ sau cắt và xoay, không mặc định là tọa độ màn hình.
84
+ - Giới hạn ảnh 32 MiB/32 triệu pixel. Chất lượng phụ thuộc ảnh, bộ chữ và thiết bị.
85
+ - Một phiên nhận dạng tại một thời điểm cho mỗi điện thoại. Các process riêng phải tự điều phối.
86
+ - APK debug không xin quyền mạng, không bỏ qua `FLAG_SECURE` hay cơ chế bảo vệ của Android.
87
+ - Dữ liệu tạm được cố gắng xóa sau mỗi request; mất kết nối hoặc dừng process đột ngột có thể để lại file.
88
+
89
+ ## Tài liệu
90
+
91
+ - [Hướng dẫn đầy đủ](README.md)
92
+ - [API và CLI](docs/API.md)
93
+ - [Giao thức Python–Android](docs/PROTOCOL.md)
94
+ - [Build APK](android/README.md)
95
+ - [Bảo mật](SECURITY.md)
96
+ - [Đóng góp và đưa lên GitHub](CONTRIBUTING.md)
97
+
98
+ Mã project dùng MIT. Thư viện/model Google giữ điều khoản riêng. Không cam kết độ chính xác hay thời gian cố định khi chưa benchmark trên ảnh thực tế.
@@ -0,0 +1,23 @@
1
+ # Security and privacy
2
+
3
+ Use ADB-MLKit only with devices and images you are authorized to access.
4
+
5
+ ## Trust boundaries
6
+
7
+ - The Android helper is a **debuggable developer tool**, not a hardened consumer app. An authorized ADB connection can access its private files through `run-as`.
8
+ - Protect USB debugging authorization, your workstation, and any ADB TCP connection. Do not expose ADB or wrap this SDK in an unauthenticated public HTTP service.
9
+ - The helper uses bundled ML Kit models and does not request network permissions. Images are processed on the selected Android device, not submitted to an OCR cloud endpoint.
10
+ - Build tooling downloads Gradle, Maven libraries, and SDK components. Offline OCR does not mean an initial build is offline.
11
+ - Google ML Kit and other dependencies retain their respective licenses and terms; the repository's MIT license covers this project's code, not Google's models.
12
+
13
+ ## Image handling
14
+
15
+ Each request uses a unique helper-private directory. The Python client attempts to remove that directory after success and failure. Cleanup is not secure erasure, and a disconnected device, killed process, or power failure can leave data behind. Results printed to a terminal or explicitly written to a file remain there.
16
+
17
+ Images already on a device are read with the shell user's existing permissions. Access to another app's private directory is not granted by this tool. It does not root devices, defeat `FLAG_SECURE`, or bypass Android storage restrictions. Device image bytes travel to the host before being staged in helper-private storage.
18
+
19
+ Do not commit personal screenshots, financial data, APK signing secrets, device identifiers, or output JSON to a public repository. The ignore rules are a convenience, not a data-loss prevention system.
20
+
21
+ ## Reporting issues
22
+
23
+ Before publishing, the repository owner should enable GitHub private vulnerability reporting. Use that mechanism when available. Do not post secrets, private screenshots, or exploitable details in a public issue; provide a synthetic reproduction and affected versions instead.
@@ -0,0 +1,11 @@
1
+ # Third-party components
2
+
3
+ ADB-MLKit's MIT license covers the integration source written for this repository. It does not relicense external software, pretrained models, platform tooling, or generated wrapper components.
4
+
5
+ - **Google ML Kit Text Recognition v2**: bundled Latin, Chinese, Devanagari, Japanese and Korean Android libraries, currently pinned in `android/app/build.gradle`. Google's license notices and [ML Kit terms](https://developers.google.com/ml-kit/terms) apply. Model implementation/source is not part of this project.
6
+ - **Android SDK / ADB / Android Gradle Plugin**: Google/Android tooling, distributed separately under their applicable terms. Android SDK license acceptance is the builder's responsibility.
7
+ - **Gradle wrapper**: generated upstream Gradle wrapper scripts/JAR; Gradle is Apache License 2.0. The wrapper downloads its pinned distribution from the official Gradle service.
8
+ - **uiautomator2 and Pillow**: optional Python dependencies for XPath-assisted screenshot capture. Consult their upstream distributions for license details.
9
+ - **JUnit**: Android JVM test dependency; consult the dependency's upstream license.
10
+
11
+ Dependency notices included in artifacts must be preserved. Review the resolved dependency tree and vendor terms before redistributing APKs, especially for commercial use. This file is an inventory, not a substitute for those licenses.
@@ -0,0 +1,88 @@
1
+ # Python API and CLI
2
+
3
+ ## Client
4
+
5
+ ```python
6
+ from adb_mlkit import ADBMLKit
7
+ client = ADBMLKit(serial=None, adb_path=None, timeout=30, script="latin")
8
+ ```
9
+
10
+ Construction/import does not contact a device. Without `serial`, exactly one authorized device must be connected. ADB is resolved from the explicit argument, `ADB_PATH`, then PATH. The client remembers the selected serial. `timeout` applies to ordinary ADB operations; instrumentation allows at least `60 + 35 * runs` seconds.
11
+
12
+ | Method | Input / output |
13
+ |---|---|
14
+ | `devices()` | All discovered `Device(serial, state, details)` records, including unauthorized devices |
15
+ | `info()` | Selected device model/API, helper installed flag and supported script list |
16
+ | `install(apk=None)` | Explicitly install/update the bundled checksum-verified APK, or a custom local APK; returns confirmation |
17
+ | `recognize_bytes(data, **options)` | Encoded image bytes; returns `OCRResult` |
18
+ | `recognize_file(path, **options)` | Local file; returns `OCRResult` |
19
+ | `recognize_device_file(path, **options)` | Absolute Android path readable by shell; returns `OCRResult` |
20
+ | `recognize_screenshot(**options)` | Capture current display using ADB screencap; returns `OCRResult` |
21
+ | `recognize_xpath(xpath, xpath_timeout=10, **options)` | Optional uiautomator2 lookup supplies screenshot ROI; returns `OCRResult` |
22
+ | `batch_files(paths, **options)` | Sequential list of local files; returns list of results, stops on first error |
23
+
24
+ All recognition methods (including batch) check for the helper on the selected device before staging input. If missing, they install the bundled checksum-verified APK automatically. An existing helper is not reinstalled or upgraded; use `install()` explicitly for updates or a custom APK. Package-query and installation failures abort recognition without staging a request. Construction, `devices()` and `info()` never install an APK.
25
+
26
+ Every successful recognition deletes its own temporary request directory on the device. Cleanup is also attempted after errors; failures generate a warning without replacing the original error. Process termination/disconnection may leave residual data.
27
+
28
+ ## Common recognition options
29
+
30
+ - `script=None`: one of `latin`, `chinese`, `devanagari`, `japanese`, `korean`; defaults to client setting.
31
+ - `language=None`: convenience alias such as `vi`, `en`, `zh`, `ja`, `ko`, `hi`. Cannot combine with `script`. Use `script_for_language()` or `LANGUAGES` to inspect aliases.
32
+ - `roi=None`: four integer pixels `(left, top, right, bottom)` before rotation. Must fit inside the image. Cannot combine with XPath's derived ROI.
33
+ - `rotation=0`: clockwise degrees, one of 0/90/180/270.
34
+ - `runs=1`: 1–30 repeated recognitions on the same image. Final run supplies output text.
35
+
36
+ These options do not request translation or linguistic correction. Model choice is script-based.
37
+
38
+ ## Result
39
+
40
+ `OCRResult` provides:
41
+
42
+ - `id`, `schema_version`, `ok`, `text`, `script`.
43
+ - `image`: original width/height, output width/height, rotation and ROI metadata.
44
+ - `timing`: Android `decode_ms`, `init_ms`, `runs_ms`.
45
+ - `host_timing`: host `load_ms`, `setup_ms`, `transfer_ms`, `instrumentation_ms`, `result_ms`, `cleanup_ms`, `total_ms`. Setup measures the helper-presence check and any automatic installation; total includes setup, so the first call may take longer. Host instrumentation time includes all runs plus process and ADB overhead. Timers overlap conceptually: do not add Android OCR times to host total.
46
+ - `blocks`: `TextBlock` objects with text, geometry, language and `lines`.
47
+ - `lines`: `TextLine` objects with nullable confidence and `elements`.
48
+ - `elements`: `TextElement` objects with text, geometry, recognized language and nullable confidence.
49
+ - `to_dict()` and `to_json(indent=2)` for export.
50
+
51
+ Geometry: `bounds` may be null; otherwise `[left, top, right, bottom]`. `corner_points` contains `[x, y]` pairs. Coordinates belong to the cropped, rotated output image. Confidence is not fabricated when unavailable. Recognized language may be empty/undetermined.
52
+
53
+ ## Errors
54
+
55
+ `ADBMLKitError` covers missing ADB, authorization/selection errors, command timeouts, invalid helper responses and Android OCR failures. Invalid arguments raise `ValueError`; unreadable local files may raise `OSError`. The JSON error categories from Android are documented in [PROTOCOL.md](PROTOCOL.md).
56
+
57
+ ```python
58
+ from adb_mlkit import ADBMLKit, ADBMLKitError
59
+ try:
60
+ result = ADBMLKit().recognize_screenshot(language="vi")
61
+ except (ADBMLKitError, ValueError, OSError) as error:
62
+ print(f"OCR failed: {error}")
63
+ ```
64
+
65
+ ## CLI
66
+
67
+ ```text
68
+ adb-mlkit [--serial SERIAL] [--adb-path PATH] [--timeout SECONDS] COMMAND
69
+
70
+ COMMAND:
71
+ devices
72
+ info
73
+ languages
74
+ install [APK]
75
+ recognize (--file PATH | --device-file PATH | --screenshot | --xpath XPATH)
76
+ batch FILE [FILE ...]
77
+
78
+ Recognition options:
79
+ --script SCRIPT | --language ALIAS
80
+ --roi LEFT TOP RIGHT BOTTOM
81
+ --rotation 0|90|180|270
82
+ --runs N
83
+ --json
84
+ --output PATH
85
+ --overwrite
86
+ ```
87
+
88
+ `--json` produces structured output only on stdout; normal text output puts timing diagnostics on stderr. `--output` saves the chosen representation to UTF-8 instead of stdout. Existing output files require explicit `--overwrite`. Batch JSON is an array in the input order. Ordinary operational errors return exit code 1; argparse usage errors return 2. `recognize` and `batch` automatically install the bundled helper if missing, without adding installation output to stdout. `install [APK]` remains available for explicit installation/updates.