个性化阅读
专注于IT技术分析

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

本文概述

几天前, 我需要发送传真(是的, 2017年人们仍在使用传真, 不要问我为什么), 看来路由器需要图像文件而不是PDF, 否则该过程可能会失败。因此, 我只是简单地通过在线服务将PDF转换为图像并完成了我的任务。如果你是需要在应用程序中实现这种有用功能的后端开发人员, 则可能需要了解没有办法使用纯PHP和纯PHP来实现。

但是, 借助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 library
composer 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-image
composer 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.单张图片

<?php

namespace 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 response
use Symfony\Component\HttpFoundation\BinaryFileResponse;
// Require PDF class of the library
use 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 response
        return new BinaryFileResponse(
            $outputImagePath
        );
    }
}

B.多页中的多张图像

默认情况下, 如果PDF有多页, 并且你使用默认代码将其转换为图像, 则始终将获得第一页的单个图像。要从每个页面生成图像, 你将需要更改PDF页面的索引。你可以通过简单地循环浏览总页数并手动更新索引来执行此操作, 然后以文件名和索引作为结果执行saveImage方法:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

// Use the normal response class
use Symfony\Component\HttpFoundation\Response;
// Require PDF class of the library
use 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 page
        foreach (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 response
        return new Response("All the pages of the PDF were succesfully converted to images");
    }
}

C.生成TMP映像而不将其保存在本地

如果你愿意从PDF生成图像而不将其保存在本地路径中, 那么你将需要在操作系统中使用PHP创建一个TMP文件, 因为包装程序需要将该文件写入某个位置。你可以使用PHP的tempnam和sys_get_temp_dir方法轻松创建临时文件:

<?php

namespace 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 response
use Symfony\Component\HttpFoundation\BinaryFileResponse;
// Require PDF class of the library
use 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 response
        return new BinaryFileResponse(
            $outputImagePath
        );
    }
}

Windows用户的问题

在Windows中, 已安装的Imagick和Ghostscript版本的体系结构必须相同, 这一点非常重要。这意味着, 如果你具有Imagick x86(32位), 则Ghostscript需要具有与x86相同的体系结构, 反之亦然。否则, 你的代码可能会遇到许多可能的异常, 例如:

PDFDelegateFailed`系统找不到指定的文件。 ‘@ error / pdf.c / ReadPDFImage / 801

编码愉快!

赞(0)
未经允许不得转载:srcmini » 如何在Symfony 3中使用PHP将PDF转换为图像

评论 抢沙发

评论前必须登录!