mostafaznv/pdf-optimizer
Optimize and compress PDFs in PHP or Laravel using Ghostscript. Fluent, chainable API with rich options, logging, and customization. Laravel-friendly inputs (paths, uploads, disks) plus queue support for async optimization.
Install Ghostscript (system requirement):
# Ubuntu/Debian
sudo apt update && sudo apt-get install ghostscript
Verify installation:
gs --version
Install the package via Composer:
composer require mostafaznv/pdf-optimizer
Publish Laravel config (if using Laravel):
php artisan vendor:publish --provider="Mostafaznv\PdfOptimizer\PdfOptimizerServiceProvider"
// Standalone PHP
use Mostafaznv\PdfOptimizer\PdfOptimizer;
$result = PdfOptimizer::init()
->settings(\Mostafaznv\PdfOptimizer\Enums\PdfSettings::SCREEN)
->optimize('input.pdf', 'output.pdf');
if ($result->status) {
echo "Optimized successfully!";
}
// Laravel (using Facade)
use Mostafaznv\PdfOptimizer\Laravel\Facade\PdfOptimizer;
$result = PdfOptimizer::fromDisk('local')
->open('input.pdf')
->toDisk('s3')
->optimize('output.pdf');
Basic Optimization
PdfOptimizer::init()
->settings(PdfSettings::PRINT) // or SCREEN, ebook, etc.
->optimize('input.pdf', 'output.pdf');
Laravel Disk Integration
PdfOptimizer::fromDisk('s3')
->open('large-file.pdf')
->toDisk('local')
->optimize('optimized.pdf');
Queue-Based Processing
// Dispatch a job
OptimizePdfJob::dispatch('input.pdf', 'output.pdf', [
'settings' => PdfSettings::SCREEN,
'resolution' => 72,
]);
// Job class
public function handle() {
$result = PdfOptimizer::init()
->settings($this->settings)
->colorImageResolution($this->resolution)
->optimize($this->input, $this->output);
}
Method Chaining: Chain settings for granular control:
PdfOptimizer::init()
->settings(PdfSettings::SCREEN)
->colorImageResolution(90)
->grayImageResolution(150)
->embedAllFonts()
->optimize('input.pdf', 'output.pdf');
UploadedFile Support:
$result = PdfOptimizer::init()
->fromUploadedFile($request->file('pdf'))
->optimize('optimized.pdf');
Custom Ghostscript Options:
PdfOptimizer::init()
->addGhostscriptOption('-dNOPAUSE')
->addGhostscriptOption('-dBATCH')
->optimize('input.pdf', 'output.pdf');
$result->status before proceeding.$result->message for debugging:
if (!$result->status) {
Log::error('PDF Optimization Failed: ' . $result->message);
}
Storage facade to compare sizes:
$originalSize = Storage::disk('local')->size('input.pdf');
$optimizedSize = Storage::disk('local')->size('output.pdf');
Ghostscript Not Found
Ghostscript binary not found.config/pdf-optimizer.php).which gs (Linux/Mac) or check PATH in Windows.Permission Issues
Failed to write output file.www-data) has write permissions to the output directory.Memory Limits
Ghostscript exited with code 1.memory_limit or optimize with lower resolutions:
->colorImageResolution(72)
->grayImageResolution(72)
Windows Compatibility
AGPL License Compliance
Enable Logging:
PdfOptimizer::init()
->enableLogging()
->optimize('input.pdf', 'output.pdf');
Logs appear in storage/logs/laravel.log.
Dry Run:
Use exportScript() to generate the Ghostscript command for manual testing:
$command = PdfOptimizer::init()
->settings(PdfSettings::SCREEN)
->exportScript('input.pdf', 'output.pdf');
echo $command; // Copy and run manually
Timeout Handling: Set a timeout to prevent hanging:
PdfOptimizer::init()
->timeout(30) // 30 seconds
->optimize('input.pdf', 'output.pdf');
Custom Settings:
Extend the PdfSettings enum or create a custom enum for project-specific presets:
class AppPdfSettings {
public const CUSTOM = 'custom-preset';
}
Queue Job Customization:
Override the default job class (OptimizePdfJob) for additional logic:
class CustomOptimizePdfJob extends OptimizePdfJob {
public function handle() {
// Pre-processing logic
parent::handle();
// Post-processing logic
}
}
Logger Integration:
Bind a custom logger in Laravel’s AppServiceProvider:
PdfOptimizer::setLogger(app(\Psr\Log\LoggerInterface::class));
Ghostscript Binary Override: Dynamically set the binary path in config or runtime:
PdfOptimizer::init()
->ghostscriptBinary('/custom/path/to/gs')
->optimize('input.pdf', 'output.pdf');
Batch Processing: Use Laravel queues to process multiple PDFs asynchronously:
foreach ($pdfFiles as $file) {
OptimizePdfJob::dispatch($file)->onQueue('optimize-pdfs');
}
Preset Optimization Profiles: Create reusable presets in a config file:
// config/pdf-optimizer.php
'presets' => [
'low_quality' => [
'settings' => PdfSettings::SCREEN,
'color_resolution' => 60,
'gray_resolution' => 72,
],
'high_quality' => [
'settings' => PdfSettings::PRINT,
'color_resolution' => 150,
'gray_resolution' => 150,
],
],
Then apply them:
PdfOptimizer::init()
->applyPreset('low_quality')
->optimize('input.pdf', 'output.pdf');
How can I help you explore Laravel packages today?