nurdin73 / pdf-stamper
Laravel PDF stamping and watermarking with TCPDF & FPDI
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/nurdin73/pdf-stamper
Requires
- php: ^8.0
- setasign/fpdi: ^2.6
- tecnickcom/tcpdf: ^6.7
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0
- phpunit/phpunit: ^10.0|^11.0
This package is auto-updated.
Last update: 2025-12-18 17:54:58 UTC
README
PdfStamper is a Laravel package for stamping, watermarking, and securing PDFs using TCPDF + FPDI.
Designed specifically for:
- Legal Documents
- Approval Workflows
- ERP / Internal Systems
- Secure Document Distribution
✨ Key Features
- Stamping:
- Text (Plain)
- HTML (
writeHTMLCell) - Images (PNG/JPG)
- Precise positioning (X, Y in mm)
- Custom rotation & colors
- Watermarking:
- Text or Image
- Flexible positions:
center,top,bottom,left,right - Layering:
under(behind content) orover(on top of content) - Opacity control (transparency)
- Security:
- PDF Password protection (Optional)
- File-level encryption (Optional)
- Developer Friendly:
- Fluent API
- Safe for loops using
resetInstance() - Centralized configuration via
applyConfig()
🔧 Requirements
- PHP >= 8.0
- Laravel >= 8.x
- PHP Extensions:
mbstring,gd
📦 Installation
Install the package via Composer:
composer require nurdin73/pdf-stamper
Publish the configuration file (optional):
php artisan vendor:publish --tag=pdf-stamper-config
⚙️ Configuration
Configuration is available at config/pdf-stamper.php:
return [ 'unit' => 'mm', 'default_font' => 'helvetica', 'default_font_size' => 12, ];
🚀 Basic Usage
1. Text Stamping
use PdfStamper; PdfStamper::resetInstance() ->fromFile($source) ->stampText('APPROVED', 100, 200, [ 'font_size' => 14, 'rotate' => 30, 'color' => '#008000', // Hex string or RGB array: [0, 128, 0] ]) ->save($output);
2. HTML Stamping
PdfStamper::resetInstance() ->fromFile($source) ->stampHtml('<b>PAID</b>', 80, 150) ->save($output);
3. Image Stamping
PdfStamper::resetInstance() ->fromFile($source) ->stampImage(storage_path('logo.png'), 50, 50, [ 'width' => 40, 'height' => 40, ]) ->save($output);
4. Watermarking
PdfStamper::resetInstance() ->fromFile($source) ->watermarkText('CONFIDENTIAL', [ 'position' => 'center', 'rotate' => 45, 'opacity' => 0.15, 'color' => '#FF0000', 'layer' => 'under', ]) ->save($output);
5. Decrypt File (Optional)
use PdfStamper; PdfStamper::decryptFile( storage_path('secure/encrypted.pdf'), 'my-secret-key', storage_path('temp/decrypted.pdf') );
6. Add Metadata to PDF
PdfStamper::resetInstance() ->fromFile($source) ->addMetadata([ 'Title' => 'Document Title', 'Author' => 'Author Name', 'Subject' => 'Document Subject', 'Keywords' => 'keyword1, keyword2', ]) ->save($output);
7. Add Custom Metadata to PDF
PdfStamper::resetInstance() ->fromFile($source) ->addCustomMetadata([ 'custom_key' => 'custom_value', ]) ->save($output);
🔁 Single Source of Truth (applyConfig)
Use applyConfig() to synchronize data from frontend/database directly with the stamping process.
$config = [ 'stamp' => [ 'type' => 'text', 'value' => 'APPROVED', 'x' => 120, 'y' => 200, 'page' => 1, 'options' => [ 'font_size' => 14, 'rotate' => 30, 'color' => '#008000', ], ], 'watermark' => [ 'text' => 'CONFIDENTIAL', 'position' => 'center', 'rotate' => 45, 'opacity' => 0.15, ], ]; PdfStamper::resetInstance() ->fromFile($source) ->applyConfig($config) ->save($output);
🔐 Security (Optional)
PDF Password
Restrict PDF access via opening password.
->encryptPdf('viewer-password')
Encrypt File (Optional)
->encryptFileWithKey('my-secret-key')
🔍 Preview vs Final Flow
| Stage | Description |
|---|---|
| Preview | Generates temporary PDF without encryption for visual validation. |
| Final | Regenerates from original source, applies security/encryption, immutable. |
Best Practice: Always regenerate the file from the original source for the Final stage. Never use a Preview output as the base for a Final file.
📐 Coordinate Tips (Frontend to Backend)
Frontend typically uses Pixels (px), while PDF uses Millimeters (mm). Use the following formula for conversion:
Formula: mm = px × 25.4 / 96
JavaScript Example:
function pxToMm(px) { return (px * 25.4) / 96; }
⚠️ Important Notes
- Reset Instance: Always call
resetInstance()before starting a new stamping process. - Looping: Do not reuse the same instance inside loops or queues without resetting.
- Preview File Management:
- Use randomized filenames.
- Set a short TTL (Time To Live).
- Store in non-public storage if possible.
📜 License
This package is open-sourced software licensed under the MIT license.