利用 php_imagick 擴展,提供「指定頁碼單張輸出」與「全頁批次輸出」兩種模式,涵蓋解析度、壓縮品質、縮放模式等關鍵參數設定。
php_imagick 擴展extension_loaded('imagick') 為 true<?php
/**
* PDF 指定頁轉 PNG
* @param string $pdfPath PDF 檔路徑
* @param string $saveDir 輸出目錄
* @param int $page 頁碼:0=第一頁,-1=全部(此函式僅處理單頁)
* @return string|false 成功回傳檔案路徑
*/
function pdf2png(string $pdfPath, string $saveDir, int $page = 0) {
if (!is_dir($saveDir)) mkdir($saveDir, 0755, true);
if (!extension_loaded('imagick')) return false;
if (!file_exists($pdfPath)) return false;
$im = new Imagick();
$im->setResolution(150, 150); // 解析度 DPI,越高越清晰但檔案越大
$im->setCompressionQuality(85); // JPEG/PNG 壓縮品質 0-100
$im->readImage("{$pdfPath}[{$page}]"); // 讀取指定頁
$im->scaleImage(300, 0, true); // 等比縮放寬度 300px,高度 0 表自動
// $im->thumbnailImage(300, 200, true); // 或用裁剪縮圖
$fileName = $saveDir . '/' . md5($pdfPath . $page . microtime(true)) . '.png';
return $im->writeImage($fileName) ? $fileName : false;
}
// 使用
$thumb = pdf2png('uploads/report.pdf', 'thumbs', 0);
if ($thumb) echo "
";
?>
<?php
function pdfAllPages2png(string $pdfPath, string $saveDir) {
if (!extension_loaded('imagick') || !file_exists($pdfPath)) return false;
$im = new Imagick();
$im->setResolution(120, 120);
$im->setCompressionQuality(90);
$im->readImage($pdfPath); // 讀取全部頁
$results = [];
foreach ($im as $i => $frame) {
$frame->setImageFormat('png');
$frame->scaleImage(250, 0); // 統一寬度
$file = $saveDir . '/' . basename($pdfPath, '.pdf') . "_page{$i}.png";
if ($frame->writeImage($file)) $results[] = $file;
}
return $results;
}
?>
| 參數 | 建議值 | 說明 |
|---|---|---|
| setResolution | 120-200 | DPI 越高文字越銳利,記憶體/CPU 成長平方 |
| setCompressionQuality | 80-90 | PNG 無損壓縮品質,檔案大小折衷 |
| scaleImage vs thumbnailImage | scaleImage | 等比縮放不裁剪;thumbnail 會裁剪填滿框 |
| 記憶體限制 | ini_set('memory_limit', '256M') | 大 PDF 需調高 |
memory_limit 或降低 DPI。$im->setBackgroundColor(new ImagickPixel('white'))。