如何在Symfony 3中使用PHP将PDF转换为图像

本文概述

  • 要求
  • 1.安装PHP包装器
  • 2.使用库
  • Windows用户的问题
几天前, 我需要发送传真(是的, 2017年人们仍在使用传真, 不要问我为什么), 看来路由器需要图像文件而不是PDF, 否则该过程可能会失败。因此, 我只是简单地通过在线服务将PDF转换为图像并完成了我的任务。如果你是需要在应用程序中实现这种有用功能的后端开发人员, 则可能需要了解没有办法使用纯PHP和纯PHP来实现。
【如何在Symfony 3中使用PHP将PDF转换为图像】但是, 借助Imagick和Ghostscript, 你可以实现这一目标, 我们将在本文中向你展示如何实现。
要求我们将要使用的库是一个包装程序, 该包装程序通过一些PHP代码抽象了命令行的用法。你将需要在计算机上专门安装以下2种工具:
  • Ghostscript安装在你的计算机上, 可以从PATH获得。
  • Imagick PHP扩展已安装和加载(请查看Windows的此安装教程)。
请记住, 需要从命令行访问Ghostscript, 这意味着bin和lib文件夹(在安装路径内, 例如C:\ Program Files(x86)\ gs \ gs9.21)需要存在于PATH环境变量中。
1.安装PHP包装器在Symfony项目中将PDF转换为图像的第一件事是安装包装器库, 该包装器为你完成命令的艰苦工作。我们正在谈论pdf到图像, 这是一个提供了一种简单的方法来与类一起将pdf转换为图像的方法。如前所述, 包装程序还依赖于已安装且正常运行的Imagick扩展程序和Ghostscript。
根据你使用的PHP版本, 你将需要安装其他版本的库:
对于PHP 7
如果使用的是PHP 7.x分支, 则可以使用该库的最新版本。使用运行以下命令的composer进行安装:
REM Download the latest version of the wrapper librarycomposer require spatie/pdf-to-image

对于PHP> = 5.5.0
由于该库的最新版本需要PHP 7或更高版本, 因此如果你使用的是PHP 5.x版本, 则还可以使用composer安装较早版本的包装器:
REM Download the 1.4.0 version of pdf-to-imagecomposer require spatie/pdf-to-image 1.4.0

有关此库的更多信息, 请访问Github上的官方存储库。
2.使用库该库的用法非常简单, 只要你在计算机上正确安装了Imagick和Ghostscript, 它就可以完美地工作。你只需要创建Spatie \ PdfToImage的Pdf类的实例, 构造函数便希望将要转换为图像的PDF的路径作为第一个参数, 然后可以简单地使用saveImage方法从生成图像。 PDF。此方法要求使用将生成的图像的文件名作为绝对路径。如果你传递给saveImage的路径具有jpg, jpeg或png扩展名, 则图像将以该格式保存。否则, 输出将为jpg。你也可以使用setOutputFormat方法强制使用格式。
在我们的示例中, 我们将强制采用png格式以使其具有透明度, 但是你可以自由使用所需的格式:
A.单张图片
< ?phpnamespace AppBundle\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; // Use the BinaryFileResponse class of Symfony to return a file as responseuse Symfony\Component\HttpFoundation\BinaryFileResponse; // Require PDF class of the libraryuse Spatie\PdfToImage\Pdf; class DefaultController extends Controller{/*** @Route("/", name="homepage")*/public function indexAction(){// Path to the PDF file that you want to convert into an image$pdfFilePath = $this-> get('kernel')-> getRootDir() . '/../web/filename.pdf'; // Path and filename of the image that will be generated// it must be absolute and with the file extension$outputImagePath = $this-> get('kernel')-> getRootDir() . '/../web/pdf_image.png'; // Create a PDF instance with the filepath of the PDF$pdf = new Pdf($pdfFilePath); // Set the format of image to the output file$pdf-> setOutputFormat('png'); // Generate image from PDF into the desired filepath$pdf-> saveImage($outputImagePath); // Return the image as responsereturn new BinaryFileResponse($outputImagePath); }}

B.多页中的多张图像
默认情况下, 如果PDF有多页, 并且你使用默认代码将其转换为图像, 则始终将获得第一页的单个图像。要从每个页面生成图像, 你将需要更改PDF页面的索引。你可以通过简单地循环浏览总页数并手动更新索引来执行此操作, 然后以文件名和索引作为结果执行saveImage方法:
< ?phpnamespace AppBundle\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; // Use the normal response classuse Symfony\Component\HttpFoundation\Response; // Require PDF class of the libraryuse Spatie\PdfToImage\Pdf; class DefaultController extends Controller{/*** @Route("/", name="homepage")*/public function indexAction(){// Path to the PDF file that you want to convert into an image$pdfFilePath = $this-> get('kernel')-> getRootDir() . '/../web/pdf_with_many_pages.pdf'; // Create a TMP file of the image with PNG format$fileName = uniqid().'.png'; // Get the path of the temporal image$outputImagePath = tempnam(sys_get_temp_dir(), $fileName); // Create a PDF instance with the filepath of the PDF$pdf = new Pdf($pdfFilePath); // Loop through every pageforeach (range(1, $pdf-> getNumberOfPages()) as $pageNumber) {// Set the index of the PDF to the page you want$pdf-> setPage($pageNumber); // Set the image format and output path$pdf-> setOutputFormat('png')-> saveImage('pdf_image'.$pageNumber.".png"); }// Return the TMP file image as responsereturn new Response("All the pages of the PDF were succesfully converted to images"); }}

C.生成TMP映像而不将其保存在本地
如果你愿意从PDF生成图像而不将其保存在本地路径中, 那么你将需要在操作系统中使用PHP创建一个TMP文件, 因为包装程序需要将该文件写入某个位置。你可以使用PHP的tempnam和sys_get_temp_dir方法轻松创建临时文件:
< ?phpnamespace AppBundle\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; // Use the BinaryFileResponse class of Symfony to return a file as responseuse Symfony\Component\HttpFoundation\BinaryFileResponse; // Require PDF class of the libraryuse Spatie\PdfToImage\Pdf; class DefaultController extends Controller{/*** @Route("/", name="homepage")*/public function indexAction(){// Path to the PDF file that you want to convert into an image$pdfFilePath = $this-> get('kernel')-> getRootDir() . '/../web/filename.pdf'; // Create a TMP file of the image with PNG format$fileName = uniqid().'.png'; // Get the path of the temporal image$outputImagePath = tempnam(sys_get_temp_dir(), $fileName); // Create a PDF instance with the filepath of the PDF$pdf = new Pdf($pdfFilePath); // Set the format of image to the output file$pdf-> setOutputFormat('png'); // Generate image from PDF into the TMP file$pdf-> saveImage($outputImagePath); // Return the TMP file image as responsereturn new BinaryFileResponse($outputImagePath); }}

Windows用户的问题在Windows中, 已安装的Imagick和Ghostscript版本的体系结构必须相同, 这一点非常重要。这意味着, 如果你具有Imagick x86(32位), 则Ghostscript需要具有与x86相同的体系结构, 反之亦然。否则, 你的代码可能会遇到许多可能的异常, 例如:
PDFDelegateFailed`系统找不到指定的文件。 ‘ @ error / pdf.c / ReadPDFImage / 801
编码愉快!

    推荐阅读