PHPackages                             lacv/pipo-scanner - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PDF &amp; Document Generation](/categories/documents)
4. /
5. lacv/pipo-scanner

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

lacv/pipo-scanner
=================

A professional document scanner component for Filament v3/v5, powered by OpenCV.js and jscanify. Capture, crop, filter and upload documents as PDF directly from the browser camera.

v1.0.1(1mo ago)00MITBladePHP ^8.1

Since Mar 30Pushed 1mo agoCompare

[ Source](https://github.com/LACV/pipo-scanner)[ Packagist](https://packagist.org/packages/lacv/pipo-scanner)[ Docs](https://github.com/LACV/pipo-scanner)[ RSS](/packages/lacv-pipo-scanner/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (2)Used By (0)

Pipo Scanner
============

[](#pipo-scanner)

A professional document scanner component for **Filament v3/v5**, powered by [OpenCV.js](https://opencv.org/) and [jscanify](https://github.com/ColonelParrot/jscanify).

Capture documents directly from the device camera, auto-detect edges, adjust corners, apply filters, and save as a multi-page PDF — all from the browser, with zero native dependencies.

> 📸 Screenshots and demo GIF coming soon.

---

Features
--------

[](#features)

- 📷 **Camera capture** with real-time automatic edge detection
- ✂️ **Manual corner adjustment** with magnifier loupe for pixel-perfect crops
- 🎨 **Three filters**: color, grayscale, black &amp; white
- 🔄 **Rotation** (90° steps) and **horizontal flip**
- 📄 **Multi-page PDF** — scan multiple pages into a single document
- 📁 **Edit mode** — open an existing document and add or replace pages
- 📱 **Mobile-first** — works on Android and iOS browsers (requires HTTPS)
- 🔒 **Secure upload** — base64 PDF sent via authenticated POST, stored on any Laravel disk

---

Requirements
------------

[](#requirements)

DependencyVersionPHP^8.1Laravel^10.0 | ^11.0 | ^12.0 | ^13.0Filament^3.0 | ^5.0Livewire^3.0> **Note:** Camera access requires **HTTPS** (or `localhost`). Plain HTTP over LAN will not expose `navigator.mediaDevices` in most browsers.

---

Installation
------------

[](#installation)

**1. Install via Composer:**

```
composer require lacv/pipo-scanner
```

**2. Publish the JS asset (required):**

```
php artisan vendor:publish --tag=pipo-scanner-assets
```

This copies `jscanify.js` to `public/vendor/pipo-scanner/jscanify.js`.

**3. Optionally publish the config:**

```
php artisan vendor:publish --tag=pipo-scanner-config
```

---

Register the Plugin
-------------------

[](#register-the-plugin)

In your panel provider (e.g. `app/Providers/Filament/AdminPanelProvider.php`):

```
use Lacv\PipoScanner\PipoScannerPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugin(PipoScannerPlugin::make());
}
```

---

Usage
-----

[](#usage)

### Recommended: `ScannerField` (native Filament field)

[](#recommended-scannerfield-native-filament-field)

Drop it directly into your form schema — no extra boilerplate needed. The field state (file path) is handled automatically by Filament, just like any other field.

```
use Lacv\PipoScanner\Forms\Components\ScannerField;

ScannerField::make('document_path')
    ->label('Document')
    ->columnSpanFull(),
```

In **edit mode** the field reads its own state (`$record->document_path`) and shows the existing document automatically — no extra code needed.

#### Available options

[](#available-options)

MethodDefaultDescription`->disk('s3')``config('pipo-scanner.disk')`Storage disk`->directory('contracts/2026')``config('pipo-scanner.directory')`Upload subdirectory`->maxFileSize(8 * 1024 * 1024)``config('pipo-scanner.max_file_size')`Max upload size in bytes`->height(450)``580`Scanner panel height in px**Full example:**

```
ScannerField::make('document_path')
    ->label('Document')
    ->disk('public')
    ->directory('documents/contracts')
    ->maxFileSize(8 * 1024 * 1024)   // 8 MB
    ->height(480)
    ->columnSpanFull(),
```

---

### Legacy: `ViewField` (manual wiring)

[](#legacy-viewfield-manual-wiring)

The original approach is still supported for backward compatibility.

It communicates back to Livewire via two mechanisms:

1. Calls `$wire.setScannerDocumentPath(path)` on the Livewire component.
2. Dispatches a browser event `scanner-saved` with `{ path, url }`.

**Step 1 — Add a method to your Livewire page/resource:**

```
public ?string $document_path = null;

public function setScannerDocumentPath(string $path): void
{
    $this->document_path = $path;
}
```

**Step 2 — Add the field to your form schema:**

```
use Filament\Forms\Components\ViewField;
use Filament\Forms\Components\Hidden;

Hidden::make('document_path'),

ViewField::make('scanner')
    ->view('pipo-scanner::components.scanner')
    ->columnSpanFull(),
```

**Step 3 — Pass existing document in edit mode:**

```
ViewField::make('scanner')
    ->view('pipo-scanner::components.scanner')
    ->viewData([
        'existingPath' => $this->record?->document_path,
        'existingUrl'  => $this->record?->document_path
            ? Storage::disk('public')->url($this->record->document_path)
            : null,
    ])
    ->columnSpanFull(),
```

---

How It Works
------------

[](#how-it-works)

```
Browser Camera
    ↓
OpenCV.js (edge detection at ~4fps, downscaled 40% for performance)
    ↓
Auto-detect document corners → draw overlay on live feed
    ↓
User captures frame (or manually adjusts corners with loupe)
    ↓
jscanify crops & perspective-corrects the image
    ↓
User selects filter: color / grayscale / B&W
    ↓
User can rotate 90° or flip horizontally
    ↓
Repeat for multiple pages (accumulated in memory)
    ↓
jsPDF compiles all pages into a single PDF
    ↓
Base64 PDF sent via POST to /pipo-scanner/upload
    ↓
Laravel stores file on configured disk
    ↓
Returns { path, url } → updates Livewire component

```

---

Events
------

[](#events)

### Browser event

[](#browser-event)

After a successful save the component dispatches:

```
$dispatch('scanner-saved', { path: 'documents/scanner/temp/scan_xxx.pdf', url: 'https://...' })
```

Listen to it with Alpine.js:

```

```

### Livewire method

[](#livewire-method)

The component automatically calls `$wire.setScannerDocumentPath(path)` on the parent Livewire component. Just define the method on your page/component:

```
public function setScannerDocumentPath(string $path): void
{
    $this->data['document_path'] = $path;
}
```

---

Configuration
-------------

[](#configuration)

After publishing the config file (`config/pipo-scanner.php`):

```
return [
    // Storage disk (default: 'public')
    'disk' => env('PIPO_SCANNER_DISK', 'public'),

    // Directory within the disk
    'directory' => env('PIPO_SCANNER_DIRECTORY', 'documents/scanner/temp'),

    // Maximum file size in bytes (default: 4MB)
    'max_file_size' => env('PIPO_SCANNER_MAX_SIZE', 4 * 1024 * 1024),

    // Upload route URL path
    'upload_route' => env('PIPO_SCANNER_UPLOAD_ROUTE', '/pipo-scanner/upload'),
];
```

Or via `.env`:

```
PIPO_SCANNER_DISK=s3
PIPO_SCANNER_DIRECTORY=scans/documents
PIPO_SCANNER_MAX_SIZE=8388608
```

---

Mobile Considerations
---------------------

[](#mobile-considerations)

- **Android**: Camera permission prompt appears on first use. The component defers `getUserMedia()` until an explicit user tap to ensure the gesture context required by Android browsers.
- **iOS (Safari)**: Supported on iOS 14.3+. Requires HTTPS.
- **HTTP on LAN**: `navigator.mediaDevices` is not exposed. Use HTTPS or `localhost`.

---

Customizing the View
--------------------

[](#customizing-the-view)

To override the default view, publish it:

```
php artisan vendor:publish --tag=pipo-scanner-views
```

The view will be copied to `resources/views/vendor/pipo-scanner/components/scanner.blade.php`.

---

Credits
-------

[](#credits)

- [OpenCV.js](https://opencv.org/) — computer vision library for edge detection
- [jscanify](https://github.com/ColonelParrot/jscanify) — document scanning library built on OpenCV.js
- [jsPDF](https://github.com/parallax/jsPDF) — client-side PDF generation

---

License
-------

[](#license)

MIT — see [LICENSE](LICENSE) file.

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance90

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

45d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f8e453192b81b1745b60c72e1f9e7d26d335c88f40680f6de009f3295585216d?d=identicon)[LuchoCruz](/maintainers/LuchoCruz)

---

Top Contributors

[![LACV](https://avatars.githubusercontent.com/u/7363539?v=4)](https://github.com/LACV "LACV (5 commits)")

---

Tags

laravelpdfdocumentscannerfilamentcameraOpenCVjscanify

### Embed Badge

![Health badge](/badges/lacv-pipo-scanner/health.svg)

```
[![Health](https://phpackages.com/badges/lacv-pipo-scanner/health.svg)](https://phpackages.com/packages/lacv-pipo-scanner)
```

###  Alternatives

[barryvdh/laravel-dompdf

A DOMPDF Wrapper for Laravel

7.3k87.6M278](/packages/barryvdh-laravel-dompdf)[barryvdh/laravel-snappy

Snappy PDF/Image for Laravel

2.8k24.8M48](/packages/barryvdh-laravel-snappy)[elibyy/tcpdf-laravel

tcpdf support for Laravel 6, 7, 8, 9, 10, 11

3542.7M5](/packages/elibyy-tcpdf-laravel)[scannerjs/scanner.js

ScannerJS: JavaScript web scan JPG PDF images from TWAIN WIA scanners in browser (Chrome, Edge, Firefox or IE)

5914.3k](/packages/scannerjs-scannerjs)[lucasromanojf/laravel5-pdf

Provides the HTML2PDF functionality using the wkhtmltopdf library (Laravel 5)

1271.8k](/packages/lucasromanojf-laravel5-pdf)[a2insights/filament-saas

Filament Saas for A2Insights

161.1k](/packages/a2insights-filament-saas)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
