问题
- 当前正在使用PDFI + TcpdF在Laravel PHP中创建实时PDF生成预览,以便用户可以导入基本PDF并在其上嵌入文本
- PDF生成对于所有大小都可以正常工作,但是大型PDF(例如A1大小)会生成10+ MB的文件,该文件太大而无法发回前端进行预览
- 寻找最快捷,最佳的方法来优化和减小PDF文件的大小,或者调整实际PDF尺寸以提供缩小版本,仅用于预览
TLDR
寻找建议(除了我在下面尝试过的建议),或者通过调整大小或将其转换为原始大PDF的图像文件来改进创建PDF预览文件的方法。
到目前为止我尝试过的事情
将PDF转换为图像 -输出大小良好(31mb> 700kb),但速度慢(1secs> 10secs)
在使用图像创建缩小的PDF之前,使用Imagick将PDF转换为图像是我的初衷,但是我发现Imagick读取PDF blob图像的速度确实很慢(与生成PDF本身相比,该过程大约需要9秒,而不到1秒)。代码如下
// $output === the PDF generated
$downscaleSizeFactor = $this->jsonFile->canvas['downscale_size_factor'] ?? 1;
$previewWidth = $this->size['width'] / $downscaleSizeFactor;
$previewHeight = $this->size['height'] / $downscaleSizeFactor;
$im = new Imagick;
$im->readImageBlob($output); // SLOW HERE!!!
$numPages = $im->getNumberImages();
$pdfPreview = new TcpdF($this->size["orientation"],'mm',[$previewWidth,$previewHeight],true,'UTF-8',false);
$pdfPreview->setPrintHeader(false);
$pdfPreview->setPrintFooter(false);
$pdfPreview->SetautoPageBreak(false,0);
for($i=0;$i<$numPages;$i++) {
$im->setIteratorIndex($i);
$selectedIm = $im->getImage();
$selectedIm->resizeImage($previewWidth,$previewHeight,imagick::FILTER_LANCZOS,1,true);
$selectedIm->setImageBackgroundColor('white');
$selectedIm->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);
$selectedIm->mergeImageLayers(Imagick::LAYERMETHOD_flaTTEN);
$selectedIm->setImageFormat('png');
$selectedIm->setImageCompressionQuality(100);
$imageString = $selectedIm->getImageBlob();
// add a page
$pdfPreview->AddPage();
// set JPEG quality
$pdfPreview->setJPEGQuality(100);
$pdfPreview->Image('@'.$imageString,$previewWidth,$previewHeight);
}
$im->clear();
$im->destroy();
return $pdfPreview->output('','S');
重新运行FPDI + TcpdF以生成缩小版本 -输出大小错误(31mb> 31mb)但速度非常快(1secs> 1.5secs)
将生成的PDF保存到临时文件夹,然后使用生成的PDF生成缩小版本,仅用于预览。就速度而言,这非常有效,但是它根本没有改变文件的大小。从[600 mm x 800 mm]减小到[10 mm x 10 mm]根本没有减小文件大小,这很奇怪。如果有人看到,我可能会错过一些东西。代码如下
$reducedPdf = new FpdiTcpdfCustom();
$tempPdfFile = storage_path('app/templates/pdf/temp/'.$name.'');
$pageCount = $reducedPdf->setsourceFile($tempPdfFile);
$pageNo = 1;
for ($pageNo; $pageNo <= $pageCount; $pageNo++) {
// Checks if the page is to be skipped
// Import a page from the blank by setting the
$pageId = $reducedPdf->importPage($pageNo);
// Return the size of the imported page
$size = $reducedPdf->getTemplateSize($pageId);
// Remove default header/footer
$reducedPdf->setPrintHeader(false);
$reducedPdf->setPrintFooter(false);
$reducedPdf->SetautoPageBreak(false,0);
// Creates the PDF page
$reducedPdf->AddPage($size['orientation'],[10,10]);
$reducedPdf->useTemplate($pageId,10,10);
}
return $reducedPdf->output('','S');
使用Spatie \ PdfToImage生成图像文件 -良好的输出大小(31mb> 218kb),但是垃圾速度(1secs> 27secs仅用于转换和保存图像)
与之前类似,在将图像调整大小并将其嵌入到PDF中进行预览之前,请先将其转换为图像文件。但是它非常慢,所以我甚至在生成PDF之前就放弃了这种方法。
$tempPdf = new \Spatie\PdfToImage\Pdf(storage_path('app/templates/pdf/temp/'.$name));
$tempPdf->setCompressionQuality(10);
$tempPdf->saveImage(storage_path('app/templates/pdf/temp/'));
建议?
有人对改善我的尝试或实现我所需的另一种方法有建议吗?