Содержание
Пару дней назад мне нужно было отправить факс (да, в 2017 году люди все еще используют факс, не спрашивайте меня, почему), и кажется, что маршрутизатору нужен файл изображения вместо PDF, иначе процесс может завершиться неудачно , Поэтому я просто преобразовал PDF с онлайн-сервисом в изображения и выполнил свою задачу. Если вы бэкэнд-разработчик, которому необходимо реализовать такую полезную функцию в вашем приложении, вам, возможно, придется знать, что нет способа сделать это с простым и чистым PHP.
Тем не менее, вы можете добиться этого благодаря Imagick и Ghostscript, и мы покажем вам, как в этой статье.
Требования
Библиотека, которую мы собираемся использовать, является оболочкой, которая абстрагирует использование командной строки с некоторым кодом PHP. На вашем компьютере должны быть установлены следующие 2 инструмента:
- Ghostscript установлен на вашем компьютере и доступны из PATH.
- Расширение Imagick для PHP установлено и загружено (проверить это руководство по установке для Windows).
Помните, что Ghostscript должен быть доступен из командной строки, это означает, что bin
а также lib
папки (внутри пути установки, например C:\Program Files (x86)\gs\gs9.21
) должен существовать в переменной окружения PATH.
1. Установите PHP Wrapper
Первое, что вам нужно сделать, чтобы преобразовать PDF-файл в изображение в вашем проекте Symfony, — это установить библиотеку-обертку, которая выполняет тяжелую работу за вас. Мы говорим о pdf-to-image, пакете, который предоставляет простой способ работы с классом для преобразования pdf в изображения. Как уже упоминалось, оболочка опирается на установленное и функциональное расширение Imagick и Ghostscript.
В зависимости от версии PHP, которую вы используете, вам нужно будет установить другую версию библиотеки:
Для PHP 7
Если вы используете ветку 7.x PHP, то вы можете работать с последней версией библиотеки. Установите его с помощью 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. Вам нужно только создать экземпляр класса Pdf Spatie \ PdfToImage, конструктор ожидает в качестве первого аргумента путь к PDF, который вы хотите преобразовать в изображение, затем вы можете просто использовать метод saveImage, чтобы сгенерировать изображение из PDF. Этот метод ожидает абсолютный путь с именем файла изображения, которое вы будете генерировать. Если путь, по которому вы переходите saveImage
имеет расширения jpg
, jpeg
, или же png
изображение будет сохранено в этом формате. В противном случае на выходе будет JPG. Вы можете форсировать формат используя setOutputFormat
метод также.
В нашем примере мы собираемся использовать его в формате png, чтобы иметь прозрачность, однако вы можете использовать тот формат, который вам нужен:
А. одиночное изображение
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
метод с именем файла и индексом как результат:
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-файла, не сохраняя его по какому-либо локальному пути, то вам потребуется создать файл TMP с PHP в вашей операционной системе, так как оболочка требует записать файл куда-нибудь. Вы можете легко создать временный файл с tempnam
а также sys_get_temp_dir
методы PHP:
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