使用TCPDF添加两张图片时生成损坏PDF的问题排查及解决
TCPDF多图片生成损坏PDF问题解决
从数据库提取图片并使用TCPDF生成PDF时,添加单张图片一切正常,但添加两张图片后会生成损坏的PDF文件——多数阅读器无法打开,仅Contao CMS的内置预览能正常显示内容。
原问题代码
单张图片正常代码
if (isset($imagePaths) && count($imagePaths) > 0) { $pdf->Image($imagePaths[0], '', '', 50, 0, '', '', '', true, 300, '', false, false, 1, false, false, false); }
添加两张图片导致损坏的代码
if (isset($imagePaths) && count($imagePaths) > 0) { $pdf->Image($imagePaths[0], '', '', 50, 0, '', '', '', true, 300, '', false, false, 1, false, false, false); $pdf->Image($imagePaths[1], '', '', 50, 0, '', '', '', true, 300, '', false, false, 1, false, false, false); }
TCPDF初始化代码
$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false); $pdf->setPDFVersion('1.7'); // 尝试过所有版本均无效 $pdf->setPrintHeader(false); $pdf->setPrintFooter(false);
问题排查
检查损坏的PDF文件内容后发现,文件缺少%%EOF等PDF必需的结尾标识。
解决方案:重新编码图片
通过对图片进行重新编码(转换为标准JPEG格式并调整尺寸)解决了该问题,优化图片的函数如下:
// 转换图片以避免PDF损坏 function optimizeAndResizeImage($imagePath, $targetWidth) { // 获取图片信息 $imageInfo = getimagesize($imagePath); // 根据图片类型加载资源 switch ($imageInfo[2]) { case IMAGETYPE_JPEG: $sourceImage = imagecreatefromjpeg($imagePath); break; case IMAGETYPE_PNG: $sourceImage = imagecreatefrompng($imagePath); break; case IMAGETYPE_GIF: $sourceImage = imagecreatefromgif($imagePath); break; default: return false; } // 计算缩放比例 $ratio = $targetWidth / $imageInfo[0]; $newWidth = (int) $targetWidth; $newHeight = (int) ($imageInfo[1] * $ratio); // 创建新尺寸的图片画布 $newImage = imagecreatetruecolor($newWidth, $newHeight); // 复制并缩放原图片到新画布 imagecopyresampled($newImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $imageInfo[0], $imageInfo[1]); // 设置优化后图片的临时路径 $tempPath = sys_get_temp_dir() . '/' . uniqid() . '.jpg'; // 保存新图片(质量设为90) imagejpeg($newImage, $tempPath, 90); // 释放图片资源 imagedestroy($sourceImage); imagedestroy($newImage); return $tempPath; }
使用优化后图片的代码
foreach ($imagePaths as $imagePath) { $optimizedImagePath = optimizeAndResizeImage($imagePath, 50 * 2.83465); if ($optimizedImagePath) { $pdf->Image($optimizedImagePath, '', '', 50, 0, '', '', '', true, 300, '', false, false, 1, false, false, false); $pdf->Ln(); // 图片后换行 $pdf->Ln(5); // 5mm空白行 // 删除临时优化图片 unlink($optimizedImagePath); } }
内容的提问来源于stack exchange,提问作者schlompf
相关产品推荐
相关产品推荐

