Search by

fatlum / nativephp-barcode-reader

Fatlum

Free QR code and barcode reading from image files for NativePHP Mobile v4: Apple Vision on iOS, ML Kit on Android. Works where PHP QR libraries cannot, because the PHP runtime on the phone has no GD or Imagick.

Package info

github.com/FatlumGjinofci/nativephp-barcode-reader

Type:nativephp-plugin

pkg:composer/fatlum/nativephp-barcode-reader

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.0.1 2026-10-19 20:11 UTC

This package is auto-updated.

Last update: 2026-10-19 20:16:28 UTC


README

A free, MIT-licensed plugin for NativePHP Mobile v4 that reads QR codes and barcodes from an image file on the device: a screenshot, a ticket photo, or anything the user picks from Photos.

PHP QR libraries cannot do this on the phone: the PHP runtime NativePHP ships has no GD and no Imagick, so they cannot read pixels. This plugin decodes natively instead:

Platform Decoder
iOS Apple Vision (VNDetectBarcodesRequest), with Core Image's QR detector as a fallback
Android ML Kit Barcode Scanning (bundled model, works offline)

Compatibility

nativephp/mobile Status
^4.4 Supported (tested on 4.4 and 4.6)
< 4.4 Not supported

PHP 8.3+, Laravel 12 or 13, iOS 15+, Android API 26+.

What's implemented

  • One synchronous call: the result comes back from the bridge, not as an event.
  • PNG, JPEG and HEIC (iOS), with EXIF orientation applied, so portrait photos work.
  • Large camera originals are downscaled to 3000 px on the longest side before decoding, so a 50 MP photo never allocates a full-size bitmap.
  • Every code in the picture, largest first, so you can skip codes your app cannot use.
  • UPC-A is reported the same way on both platforms (upca, 12 digits); Vision would otherwise report it as a 13-digit EAN-13.

This plugin reads codes from images. It does not open a live camera scanner.

Install

composer require fatlum/nativephp-barcode-reader
php artisan vendor:publish --tag=nativephp-plugins-provider   # once per app, if not done yet
php artisan native:plugin:register fatlum/nativephp-barcode-reader

Developing the plugin next to your app

Clone it into a sibling folder and install it from there through a path repository; Composer symlinks it, so edits show up in the app immediately:

composer config repositories.nativephp-barcode-reader '{"type": "path", "url": "../nativephp-barcode-reader", "options": {"symlink": true}}'
composer require fatlum/nativephp-barcode-reader:@dev
php artisan native:plugin:register fatlum/nativephp-barcode-reader

Usage

use Lumi\NativeBarcodeReader\Facades\BarcodeReader;

// e.g. the path from Camera::pickImages()'s MediaSelected event
$code = BarcodeReader::read($path);

if ($code === null) {
    // no code found, unreadable image, or not running on a device
} else {
    $code['value'];  // "PF-00482193"
    $code['format']; // "qr", "aztec", "pdf417", "code128", "ean13", "ean8", "upca", "upce",
                     // "code39", "code93", "itf", "datamatrix" or "codabar"
}

// Every code in the picture, largest first
foreach (BarcodeReader::readAll($path) as $code) {
    // ...
}

BarcodeReader::isAvailable(); // false in the browser or when the plugin is not compiled in

$path may be an absolute path or a file:// URL (Android also accepts content://).

Picking a photo and reading its code

use Lumi\NativeBarcodeReader\Facades\BarcodeReader;
use Native\Mobile\Attributes\On;
use Native\Mobile\Events\Gallery\MediaSelected;
use Native\Mobile\Facades\Camera;

public function codeFromPhoto(): void
{
    Camera::pickImages('image')->id('code')->start(); // needs nativephp/mobile-camera
}

#[On(MediaSelected::class)]
public function onMediaSelected(bool $success, array $files = [], ?string $id = null): void
{
    $path = $files[0]['path'] ?? null;
    $code = $success && $path ? BarcodeReader::read($path) : null;

    // ...
}

JavaScript (Vue, React, Inertia, web-view apps)

Livewire, Blade and NativeComponent screens use the PHP facade above. Apps that call native code from JavaScript can import the helpers shipped in resources/js/barcodeReader.js:

import { read, readAll } from '../../vendor/fatlum/nativephp-barcode-reader/resources/js/barcodeReader.js';

const code = await read(path);     // { value: 'PF-00482193', format: 'qr' } or null
const codes = await readAll(path); // [{ value, format }, ...] largest first

They post to NativePHP's /_native/api/call route (sending the csrf-token meta tag when the page has one) and, like the PHP facade, never throw: no code, an unreadable image, a missing plugin or no device all resolve to null / [].

AI guidelines (Laravel Boost)

The plugin ships Boost guidelines in resources/boost/guidelines/core.blade.php. Apps that use Laravel Boost pick them up on php artisan boost:install, so AI assistants use this plugin, not a PHP QR library, to read codes on the phone.

Bridge function

Name Parameters Returns
BarcodeReader.Read path {found, value?, format?, codes: [{value, format}]}, largest code first; an error response when the image cannot be read

Testing in your app

use Native\Mobile\Testing\Native;

Native::fakeBridge()->respondTo('BarcodeReader.Read', [
    'found' => true,
    'value' => 'PF-00482193',
    'format' => 'qr',
]);

Developing

composer install
composer test      # PHPUnit: PHP facade and manifest
composer test:js   # Node's test runner: JavaScript helpers (Node 22+)

GitHub Actions runs both on every push and pull request: PHP 8.3 and 8.4 against Laravel 12 and 13, plus the JavaScript tests.

The native Swift and Kotlin code has no automated tests; check it on real devices before a release (php artisan native:run ios / native:run android in an app that uses the plugin). On the iOS simulator Vision cannot run ("Could not create inference context"), so only QR codes are read there, through Core Image.

License

MIT