Как с помощью php и ImageMagick разбить PDF на отдельные листы

Как с помощью php и ImageMagick разбить PDF на отдельные листы

Столкнулся с небольшой, но интересной задачкой – необходимо разбить PDF-файл, который состоит из нескольких страниц, на отдельные листы. Разобрать pdf необходимо так, чтобы каждый ее лист стал картинкой. Задачка не часто встречается, поэтому про нее стоит написать заметку, вдруг кому-нибудь еще пригодится.

Как с помощью ImageMagick разбить PDF на страницы

Для этой задачи отлично подходит программа ImageMagick, которая в основном используется для работы с графикой. ImageMagick установлена по умолчанию, практически, на всех хостингах. А если не установлена, то служба поддержки без проблем может ее добавить для вашего сайта. Если же у вас не хостинг, а свой сервер, то можете сами добавить программу, это занимает всего пару минут.
После того, как программа установлена, достаточно всего одной команды, чтобы разбить pdf на отдельные страницы:

// Разбить всю PDF на отдельные листы
convert test.pdf -quality 100 page-%3d.png 
// Взять только вторую страницу из PDF
convert test.pdf[1] -quality 100 page-2.png 

Разбивка PDF с помощью ImageMagick в php

Работать с ImageMagick в php так же просто, как и через консоль. Но есть несколько нюансов, про которые стоит упомянуть.
При обращении к файлам, лучше использовать абсолютный путь. Относительные пути к файлам не всегда определяются ImageMagick и часто вылетают ошибки. Для указания полного пути к файлу удобно использовать константу __DIR__.
Второе. При сохранении картинок в формате jpeg качество листов сильно отличается от оригинала. Даже если задавать максимальное качество и отключать оптимизацию, то искажения картинок все равно видны на глаз. Лучше сохранять в формате png, тогда качество листов-картинок будет, как в исходном файле.
Третий важный момент заключается в том, что если PDF не имеет заданного фона, то png картинки будут создаваться с прозрачностью. Если прозрачность не нужна, то нужно ее отключить перед сохранением картинки. Сделать это можно с помощью флага setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE).
Далее приведен код разбивки PDF на отдельные листы. Каждая строка прокомментирована, чтобы было проще понять логику.

// полный путь к PDF
$pdf = __DIR__ . "/test.pdf";
// открытие PDF
$im = new imagick($pdf);
// определение количества листов в PDF
$count_pages = $im->getNumberImages(); 
// если есть хотя бы один лист
if ($count_pages) { 
	for ($i = 0; $i < $count_pages; $i++) {
		// вытаскиваем одну страницу
		// номер страницы(от 0 до $count_pages)
		$page = $pdf.'['.$i.']'; 
		// создание холста из одной страницы PDF
		$image = new Imagick($page);			
		// формат картинок
		$image->setImageFormat("png"); 
		// отключение прозрачности, чтобы пустые места на картинках страниц стали белыми
		$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);
		// качества картинок(0-100)
		$image->setImageCompressionQuality(100);
		// сохранение картинки с именем НОМЕР-page.png
		$image->writeImage(__DIR__."/".($i+1).'-page.png'); 
	}
}
 

Как с помощью php вытащить один лист PDF

Не всегда нужно разбирать всю PDF на отдельные страницы. Чтобы взять одну конкретную страницу, не обязательно разбивать всю пдф на листы и выбирать требуемый. Можно сразу вытащить нужный лист. Код примера приведен ниже, в нем из всего PDF-файла извлекается только вторая страница.

// вытащить одну страницу
// нумерация страниц начинается с нуля
$pdf = __DIR__ . "/test.pdf";
$page = $pdf.'[1]';  // [1] - номер страницы
$image = new Imagick($page);	
$image->setImageFormat("png"); 
$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);
$image->setImageCompressionQuality(100);
$image->writeImage(__DIR__."/2-page.png");
 

Послесловие

Во всех примерах pdf конвертировалось в png картинки. Но листы можно сохранить и в формате pdf. Ниже приведен пример кода.

// Сохранить одну страницу в формате pdf
// Путь к pdf и в квадратных скобках номер страницы
// Нумерация страниц начинается с нуля
$page = __DIR__ . "/test.pdf[1]";
$image = new Imagick($page);	
$image->setImageFormat("pdf"); 
$image->setImageCompressionQuality(100);
$image->writeImage(__DIR__."/2-page.pdf");

Рассказать друзьям:


Оценить:
(8 оценок, среднее: 3,25 из 5)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

code