Installation:
composer require spatie/pdf-to-image
Ensure PHP 8.2+ and dependencies (Imagick, Ghostscript) are installed.
First Use Case: Convert a PDF to an image (default: first page, JPG format):
use Spatie\PdfToImage\Pdf;
$pdf = new Pdf(storage_path('example.pdf'));
$pdf->save(storage_path('output.jpg'));
Key Files:
Pdf class: Core functionality.Enums/OutputFormat.php: Supported formats (JPG, PNG, WEBP).DTOs/PageSize.php: PDF dimensions.Single Page Conversion:
$pdf = new Pdf($path);
$pdf->selectPage(2) // Optional: Select page 2
->quality(90) // Optional: Set quality
->save($outputPath);
Batch Processing (Multiple Pages):
$pdf = new Pdf($path);
$pdf->selectPages(1, 3, 5) // Pages 1, 3, and 5
->format(\Spatie\PdfToImage\Enums\OutputFormat::Png)
->save(storage_path('images/'));
All Pages to Images:
$pdf = new Pdf($path);
$pdf->saveAllPages(storage_path('all_pages/'));
Dynamic Output (Laravel Example):
use Illuminate\Support\Facades\Storage;
$pdf = new Pdf(Storage::path('uploads/example.pdf'));
$output = $pdf->size(800, 600)
->backgroundColor('white')
->save(Storage::path('converted/'));
Queue Jobs for Large PDFs: Use Laravel queues to avoid timeouts:
ConvertPdfJob::dispatch($pdfPath, $outputPath)->onQueue('pdf-conversions');
Store in S3:
use Illuminate\Support\Facades\Storage;
$pdf = new Pdf($localPath);
$output = $pdf->save(Storage::disk('s3')->path('converted.jpg'));
Validation: Check PDF existence and format:
if (!file_exists($path) || !$pdf->isValidOutputFormat('png')) {
throw new \InvalidArgumentException('Invalid PDF or format.');
}
Custom Naming:
Use str_replace or pathinfo to generate filenames dynamically:
$filename = 'page_' . $pageNumber . '.jpg';
$pdf->selectPage($pageNumber)->save(storage_path('pages/' . $filename));
Ghostscript/Imagick Dependencies:
Error: FailedToExecuteCommand 'gs' (PHP-FPM).
Fix: Update php-fpm.conf:
env[PATH] = /usr/local/bin:/usr/bin:/bin
Restart PHP-FPM after changes.
Policy Errors:
Add to /etc/ImageMagick-[VERSION]/policy.xml:
<policy domain="coder" rights="read | write" pattern="PDF" />
<policy domain="resource" name="width" value="4GiB"/>
<policy domain="resource" name="height" value="4GiB"/>
Ultra-Wide PDFs:
policy.xml resource limits for large files (see above).Transparent Backgrounds:
backgroundColor to avoid transparency issues:
$pdf->backgroundColor('white');
Page Counting:
pageCount() uses pingImage() (lazy loading). Avoid repeated calls in loops.File Permissions:
$directory = storage_path('converted');
if (!file_exists($directory)) mkdir($directory, 0755, true);
Check Imagick Version:
$imagick = new \Imagick();
echo $imagick->getVersion(); // Verify Ghostscript/Imagick compatibility.
Log Errors: Wrap conversions in try-catch:
try {
$pdf->save($output);
} catch (\ImagickException $e) {
Log::error('PDF conversion failed: ' . $e->getMessage());
}
Test Locally First:
Use php artisan tinker to test configurations before deploying:
$pdf = new \Spatie\PdfToImage\Pdf(storage_path('test.pdf'));
$pdf->resolution(300)->save(storage_path('test.jpg'));
Custom Output Paths:
Extend the Pdf class to add logic for dynamic paths:
class CustomPdf extends Pdf {
public function saveToCustomPath($basePath) {
$filename = 'custom_' . $this->getPageNumber() . '.jpg';
return $this->save($basePath . '/' . $filename);
}
}
Post-Processing:
Use Laravel's Image facade to manipulate images after conversion:
use Intervention\Image\Facades\Image;
$pdf->save($tempPath);
$image = Image::make($tempPath)->resize(400, 300)->save($outputPath);
Event Listeners: Trigger events before/after conversion:
$pdf->converting(function () {
Log::info('Starting PDF conversion...');
});
Configuration: Override defaults via service provider:
$this->app->singleton(Pdf::class, function () {
return new Pdf($path, [
'default_format' => \Spatie\PdfToImage\Enums\OutputFormat::Webp,
'default_quality' => 85,
]);
});
Cache Page Counts:
Store pageCount() results in a database or cache to avoid repeated calls.
Batch Processing:
Use Laravel's chunk() for large PDFs:
$pdf = new Pdf($path);
$pages = range(1, $pdf->pageCount());
foreach (array_chunk($pages, 10) as $chunk) {
$pdf->selectPages(...$chunk)->save(storage_path('batch/'));
}
Optimize Resolution: Lower DPI for non-critical conversions (e.g., 150 instead of 300).
```markdown
### Pro Tips
- **Combine with Laravel Filesystem**:
Use `Storage::disk('s3')->put()` to upload converted images directly to cloud storage.
- **Laravel Nova Integration**:
Add a custom action to convert PDFs attached to resources:
```php
Nova::serving(function () {
Nova::action('Convert PDF', 'convertPdf', function (NovaAction $action) {
$pdf = new \Spatie\PdfToImage\Pdf($action->resource->pdf_path);
$pdf->save(storage_path('nova_converted/' . $action->resource->id . '.jpg'));
return Action::message('PDF converted!');
});
});
Pdf class in unit tests:
$mockPdf = Mockery::mock(Pdf::class)->makePartial();
$mockPdf->shouldReceive('save')->andReturn('path/to/image.jpg');
How can I help you explore Laravel packages today?