protendai/nativephp-mobile-ocr
FakeBridge test double. A PM can scope features like receipt capture, invoice/PO intake, ID and form scanning, asset-tag lookup, or "add note from photo" and ship them from the PHP codebase instead of staffing an iOS/Android workstream.RecognitionFailed::CAMERA_PERMISSION_DENIED), and both present full-screen so users can't swipe away without a result event. A PM can write one acceptance criterion and have it hold on both platforms — a real reduction in QA and support load.Layout::rows() and Layout::valueBeside() are unit-agnostic, so "label to the right of the label" extraction (totals, dates, names on forms) is the recommended path. This is a product-level decision worth recording: build extraction on relational geometry, not hardcoded pixel assumptions.$path to your own storage — not something you get for free.capture()/scan() at a time; a second call fails fast with BUSY. Design flows as single-shot, and surface a friendly retry rather than assuming queued scans.NSCameraUsageDescription ships in the manifest and Android launches are guarded, so no app-side Info.plist edits and no crash-on-prompt. That removes a recurring App Store rejection cause and a class of 1-star reviews.Adopt when most of these hold:
recognize(), capture(), scan(), rows(), event listeners) with TypeScript types.FakeBridge macros.Look elsewhere, or plan to wrap another service, when:
BUSY semantics make this a build, not a config.Layout::rows()/valueBeside() is unaffected; anything that read fractions directly must divide by width/height (now on TextRecognized, nullable from older native code). Treat this as a breaking change for early adopters and audit before upgrading — it is the one item in this release that needs a migration note, not just a changelog entry.To executives: This is the 1.0 of our on-device text recognition capability, and it changes the economics of our scanning features. It is MIT-licensed and does the hard, expensive part — camera, permissions, orientation, memory, temp files, parity across iOS and Android — inside the Laravel codebase we already staff. There is no per-scan cost and no image ever leaves the device, which is both a margin story and a compliance story we can put in front of customers. The v1.0 marker matters for planning: the platform risk that makes scanning demos fail on stage — permission crashes on older Android, out-of-memory on modern 50–108 MP cameras, iOS reporting a denial as a user cancel — is fixed and covered by tests. We can commit to scanning features on the roadmap without a native hiring plan.
To engineering: Adopt it, and read two things before you start. First, iOS boxes are now pixels of the upright image with a top-left origin, matching Android — if any prototype parsed raw 0–1 fractions, that code needs a one-line divide by the new width/height on TextRecognized, which are optional and null from older native code so existing handlers still compile. Second, build on Layout::rows() and Layout::valueBeside(); they are unit-agnostic and immunize you against future coordinate changes — that's the migration-proof seam. Beyond that, the release closes real defects: Android capture() no longer touches MediaStore (no more SecurityException on 8/9, no stray empty gallery file; photos go through the core FileProvider), downscaled decode with retry-smaller on OutOfMemoryError, commitNowAllowingStateLoss() for calls during activity teardown, temp files deleted on cancel/failure, camera presented full-screen on iOS so no swipe-away without a result. The constraints to design around: one capture/scan at a time (RecognitionFailed::BUSY — handle it, don't retry blindly), images are pruned from the plugin cache on the next capture (copy $path immediately if you need to keep it), and inputs are downscaled to 4096 px so boxes refer to that image — spike accuracy on dense documents before committing to one. Error handling is now a single taxonomy on both platforms: check isPermissionDenied() and isBusy() rather than string-matching, and the whole surface is testable in CI through the facade and FakeBridge macros. Floors are Android 21 and iOS 13.
How can I help you explore Laravel packages today?