Repository navigation
Add flags for Fayda barcode reading and full-resolution OCR crops - #1870
Open
BurningAXE wants to merge 2 commits into
Open
BurningAXE wants to merge 2 commits into
BurningAXE wants to merge 2 commits into
Conversation
BurningAXE
force-pushed
the
feature/fayda-barcode-and-native-res-ocr
branch
from
October 19, 2026 21:54
223bbfa to
b3a1548
Compare
BurningAXE
added this pull request to stack #1873
October 20, 2026 11:03
There was a problem hiding this comment.
🟡 Changes recommended
Barcode aggregation can produce a FAN that was never decoded or checksum-verified.
1 open issue
What changed in this PR
Adds two opt-in improvements to MFID scanning: full-resolution OCR crops and barcode-first Fayda FAN reading. Both flags default to disabled.
Changes:
- Preserve capture detail without downscaling to preview size.
- Read Fayda Code 128 barcodes, falling back to OCR and preferring barcode results.
- Add configuration, crop, reader, and flag-propagation tests.
| File | Description |
|---|---|
| infra/config-store/src/test/java/com/simprints/infra/config/store/models/ExperimentalProjectConfigurationTest.kt | Tests both flag defaults and values. |
| infra/config-store/src/main/java/com/simprints/infra/config/store/models/ExperimentalProjectConfiguration.kt | Defines the experimental flags. |
| infra/camera/src/test/java/com/simprints/infra/camera/usecase/NormalizeHighResBitmapToPreviewUseCaseTest.kt | Tests skipped downscaling. |
| infra/camera/src/test/java/com/simprints/infra/camera/postprocess/FrameCropToTargetUseCaseTest.kt | Tests native-resolution cropping. |
| infra/camera/src/main/java/com/simprints/infra/camera/usecase/NormalizeHighResBitmapToPreviewUseCase.kt | Makes preview downscaling optional. |
| infra/camera/src/main/java/com/simprints/infra/camera/CameraFrameProvider.kt | Passes the resolution preference. |
| feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/ScanMfidDocumentUseCaseTest.kt | Tests barcode routing and OCR fallback. |
| feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/FaydaCardOcrReaderUseCaseTest.kt | Tests barcode validation and bounds. |
| feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/BuildMfidDocumentUseCaseTest.kt | Tests barcode preference. |
| feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrViewModelTest.kt | Tests barcode flag propagation. |
| feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/ScanMfidDocumentUseCase.kt | Adds barcode-first Fayda scanning. |
| feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/ReadBarcodesFromImageUseCase.kt | Adds Code 128 detection. |
| feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/FaydaCardOcrReaderUseCase.kt | Converts barcodes into FAN results. |
| feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/BuildMfidDocumentUseCase.kt | Prioritizes barcode readouts. |
| feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/reader/ScannedBarcode.kt | Models decoded barcode data. |
| feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/model/OcrScanResult.kt | Records barcode provenance. |
| feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/model/OcrConfig.kt | Carries both scanning flags. |
| feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrViewModel.kt | Loads and forwards configuration. |
| feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrFragment.kt | Configures full-resolution capture detail. |
| feature/external-credential/build.gradle.kts | Adds the barcode scanning dependency. |
Review effort: Balanced
BurningAXE
force-pushed
the
feature/fayda-barcode-and-native-res-ocr
branch
from
October 20, 2026 11:14
b3a1548 to
2896e03
Compare
BurningAXE
removed this pull request from stack #1873
October 20, 2026 11:19
BurningAXE
added this pull request to stack #1874
October 20, 2026 11:22
BurningAXE
marked this pull request as ready for review
October 20, 2026 11:23
BurningAXE
requested review from
a team,
TristramN,
alex-vt,
alexandr-simprints,
luhmirin-s,
meladRaouf and
ybourgery
and removed request for
a team
October 20, 2026 11:24
With ocrHighRes enabled, each frame is a full-quality still capture that is then scaled down to the preview size before the scan area is cropped, which discards the detail the capture was taken for. On a Galaxy J6 the Fayda FAN ended up 7-9px tall, below what ML Kit reads reliably. The new experimental flag (default false, no behaviour change) skips the downscale so FrameCropToTargetUseCase crops the scan area from the native-resolution capture. In testing this made the FAN ~40-60px tall and OCR matched 6/7 frames instead of 3/8, at the cost of slower OCR per frame. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fayda cards carry the FAN in a Code 128 barcode below the printed number. Barcode decoding is checksummed, so unlike OCR it does not misread digits, and it works at distances where the printed FAN is too small for OCR. When the new experimental flag is enabled (default false, no behaviour change), Fayda scans try the barcode first and only fall back to OCR when no barcode with a valid FAN is found or barcode detection fails. When any capture came from a barcode, the most frequent barcode value is used as the final FAN instead of per-digit voting, so OCR misreads cannot outvote it and differing barcode reads cannot be merged into a value that was never decoded. NHIS and Ghana ID scans are not affected. In testing on a Galaxy J6 this brought a full capture down to ~10-20s with no misread FANs (from ~48s with one misread). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BurningAXE
force-pushed
the
feature/fayda-barcode-and-native-res-ocr
branch
from
October 20, 2026 11:51
2896e03 to
3d0503f
Compare
luhmirin-s
approved these changes
Oct 20, 2026
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




JIRA ticket
Will be released in: 2026.3.1
Root cause analysis (for bugfixes only)
First known affected version: 2026.3.0
ocrHighReson (the default), each frame is a full-quality still capture that is scaled down to the preview size before the scan area is cropped. The crop ended up 664×415 and the FAN text 7–9px tall, below what ML Kit reads reliably. OCR read the FAN in only 3 of 8 frames (one with a wrong digit), and a capture took ~48s.Notable changes
Two independent commits, each behind an experimental custom-config flag that defaults to
false, so there is no behaviour change unless enabled per project. Either commit can be reverted on its own.ocrKeepHighResDetail: crop OCR frames from the full-resolution captureNormalizeHighResBitmapToPreviewUseCasegets ascaleToPreviewparameter (defaulttrue).CameraFrameProvider.initialiseCameragetskeepHighResolutionDetail(defaultfalse), which the OCR screen sets from the flag.FrameCropToTargetUseCasealready supports bitmaps of any size, so it is unchanged.ocrHighResis on, and only on the OCR screen (all MFID card types). Face capture and the QR scanners never use high-res capture and are not affected.ocrReadFaydaBarcode: read the FAN from the card's barcode first, falling back to OCRReadBarcodesFromImageUseCase(ML Kit, Code 128 only) andFaydaCardOcrReaderUseCase.fromBarcodes(). The first barcode whose value is exactly 16 digits wins, and its box is extended upwards so the zoomed preview also shows the printed FAN.ScanMfidDocumentUseCasetakes areadFaydaBarcodeparameter, passed from the view model'sOcrConfiglike the existing OCR flags. When the barcode gives a FAN, OCR is skipped for that frame. If barcode detection fails (e.g. the Play Services barcode module isn't downloaded yet), the frame falls back to OCR. NHIS and Ghana ID scans never read barcodes.OcrScanResult.FaydaCardgets anisFromBarcodefield (defaultfalse). When any capture came from a barcode,BuildMfidDocumentUseCaseuses the most frequent complete barcode value instead of per-digit voting. This way OCR misreads can't outvote the checksummed value, and differing barcode reads can't be merged into a FAN that was never decoded. Per-digit voting is still used when all captures came from OCR.play-services-mlkit-barcode-scanningtofeature:external-credential. The app already ships it viainfra:camerafor QR scanning.Results on the Galaxy J6 (same card, each feature tested in isolation):
ocrKeepHighResDetailocrReadFaydaBarcodeocrReadFaydaBarcode+ocrHighRes: falseocrKeepHighResDetailmakes OCR on each frame slower (1.6–3s vs 0.4–2s) and makes saved scan images bigger.ocrHighRes: false(existing flag) is only fast when users hold the phone close to the barcode. With the whole card in frame, stream frames are too low-res for the barcode.Testing guidance
ExperimentalProjectConfigurationTest,NormalizeHighResBitmapToPreviewUseCaseTest,FrameCropToTargetUseCaseTest,FaydaCardOcrReaderUseCaseTest,ScanMfidDocumentUseCaseTest,BuildMfidDocumentUseCaseTest,ExternalCredentialScanOcrViewModelTest."ocrReadFaydaBarcode": true: framing the whole card should capture in ~10–20s. Holding the phone very close (barcode out of view) still works via OCR."ocrKeepHighResDetail": true: OCR should pick up the FAN with the whole card in frame. Check frame times on low-end devices."ocrHighRes": falsewith the barcode flag: holding the phone close to the barcode should capture in ~1s.ocrKeepHighResDetail.Additional work checklist
🤖 Generated with Claude Code