Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nativephp Mobile Ocr Laravel Package

protendai/nativephp-mobile-ocr

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install the package with Composer, then run the NativePHP install/sync step so native sources and the manifest are registered. Confirm the manifest now targets android.min_version 21 and ios.min_version 13.0.
  • Look first at:
    • The README and Boost guidelines for recognize(), capture(), scan(), events, and layout helpers.
    • src/Events/TextRecognized.php and src/RecognitionFailed.php for the result contract.
    • src/Layout.php for rows() and valueBeside().
    • resources/js/index.js and its TypeScript types for Inertia/Vue/React usage.
    • The tests for facade, events, FakeBridge macros, JS library, and manifest/native consistency.
  • First use case: scan a receipt or invoice page, listen for TextRecognized, pass the recognized lines through Layout::rows(), and parse the resulting rows into structured line items. This avoids depending on raw box coordinates and works across Android and iOS.
use App\Events\DocumentScanned;
use NativePHP\TextRecognition\Facades\TextRecognizer; // use the facade name from the README

TextRecognizer::scan(); // opens the native document scanner

Then handle the result in a listener/controller:

use NativePHP\TextRecognition\Events\TextRecognized;
use NativePHP\TextRecognition\Layout;

public function handle(TextRecognized $event): void
{
    $rows = Layout::rows($event->lines);

    // $rows is unit-agnostic; no need to normalize iOS fractions manually.
    $invoiceNumber = Layout::valueBeside($event->lines, 'Invoice');
}

Implementation Patterns

  • Choose the right entry point.
    • recognize($path) for images already on disk.
    • capture() when you want a single photo from the camera.
    • scan() when you want the native document scanner with edge detection/cropping.
  • Correlate requests by id. Each capture()/scan() request has its own id, and failures arrive for that id. Keep the id in component state so a RecognitionFailed does not clear the wrong UI.
  • Handle permission and busy states explicitly.
use NativePHP\TextRecognition\RecognitionFailed;

public function failed(RecognitionFailed $event): void
{
    if ($event->isPermissionDenied()) {
        $this->showPermissionHelp = true;
        return;
    }

    if ($event->isBusy()) {
        $this->status = 'Another capture or scan is already open.';
        return;
    }

    $this->status = $event->message;
}
  • Use layout helpers instead of raw coordinates. Layout::rows() and Layout::valueBeside() are unit-agnostic, so they are the safest way to build forms, tables, and key/value extraction. Use width/height only when you need to normalize or map boxes yourself.
  • Normalize coordinates when needed.
$x = $box->left / $event->width;
$y = $box->top / $event->height;

Guard against null dimensions from older native code before dividing.

  • Copy image paths you need to keep. Captured photos and scanned pages live in a plugin cache folder. Starting a later capture or scan removes older files, each after at least a minute. If the path is part of a saved record, copy it to storage/app/... immediately.
  • Use the JS library for Inertia and Vue/React flows. Import recognize, capture, scan, event listeners, and rows() from resources/js/index.js (or the published package entry point). This is the shortest path for SPA-style screens that should not round-trip through a full page reload.
  • Test with FakeBridge macros. Fake successful recognition and failure events in feature tests, then assert your listener/controller behavior. This is especially useful for permission-denied, busy, and cancellation paths.
  • Treat recognition as asynchronous. Disable the capture/scan button while a request is pending, show progress, and always provide a cancel/retry path. The native camera and scanner are presented full screen, so the user cannot swipe them away without producing a result event.

Gotchas and Tips

  • iOS coordinates changed in v1.0.0. Boxes are now pixels of the upright image with a top-left origin, matching Android, instead of 0–1 fractions. Code that read raw iOS fractions must divide by width/height. Code using Layout::rows() or Layout::valueBeside() is unaffected.
  • width and height are optional. Older native code can send null. Do not assume they are always present; fall back gracefully or skip coordinate normalization.
  • Boxes refer to the processed image, not necessarily the original file. Large photos are downscaled before recognition, with the longest side capped at 4096 px and EXIF orientation applied. If you map boxes back to the original image, scale using the reported width/height versus the original dimensions.
  • Only one capture() or scan() can be open at a time. A second call receives RecognitionFailed::BUSY for its own id instead of silently orphaning the first request. Disable duplicate actions in the UI.
  • Do not rely on the gallery on Android. capture() no longer inserts into MediaStore; photos go to the app cache through the NativePHP core FileProvider. This fixes crashes and empty gallery files on Android 8/9, but it also means users will not find captures in their photo gallery.
  • Cache files are temporary. Copy $path if you need persistence. Temp files are also deleted when the user cancels or the capture fails.
  • iOS permission failures now arrive as RecognitionFailed('Camera permission denied'), the same as Android, instead of ScanCancelled. Do not use cancellation as a proxy for permission denial.
  • The iOS permission description is already declared. NSCameraUsageDescription is in the manifest, so capture() and scan() work without app-side Info.plist edits. If you customize permission text, verify the manifest merge.
  • Minimum platform versions are real. Android 21 and iOS 13 are the lowest the native code supports. Check these before debugging device-specific behavior.
  • Full-screen camera/scanner changes cancellation behavior. The user cannot swipe the native screen away without a result event. Make sure your app still exposes a clear cancel action and handles the resulting cancellation/failure event.
  • Debugging checklist: log the request id, event class, width/height, and first few box coordinates; verify whether the path still exists; confirm only one capture/scan is active; test on Android 8/9 and with a very high-resolution photo; and use FakeBridge to isolate PHP-side handling from native behavior.
  • Extension points: use the facade and events for normal flows, FakeBridge macros for tests, Layout helpers for text reconstruction, and the JS event listeners for custom Inertia/Vue/React UIs. If you need custom native behavior, follow the moved native source layout under resources/android/src/ and resources/ios/Sources/.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums