Я пытаюсь написать процедуру, которая будет принимать PDF-файл, предоставленный пользователем, и извлечь каждую страницу в качестве изображения, а затем заполнить массив этими изображениями. Я нашел несколько примеров, которые добавляют все страницы к одному изображению, но ни один из них не делает то, что мне нужно.
Это то, что у меня есть, но он возвращает пустой массив:
function PdfToImg($pdf_in) { $img_array = array(); $im = new imagick(); $im->readimageblob($pdf_in); // reading image from binary string $num_pages = $im->getnumberimages(); $im->setimageformat("png"); for ($x =1;$x <= $num_pages; $x++) { $img = $im->previousimage(); $img_array .= $img; } return $img_array; }
Одно из предостережений здесь состоит в том, что я не могу записать эти файлы на диск, должен использовать строки / массивы. Я просмотрел руководство ImageMagick и ничего не нашел о выводе нескольких изображений в массив, а только в ряд файлов, сохраненных на диске.
ОБНОВЛЕНИЕ: (06/13/2012) Я нашел способ добиться того, что мне нужно, но он уродлив, неэффективен, и я уверен, что он медленный, но, похоже, не было другого пути.
function PdfToImg3($pdf_in) { $img_array = array(); $im = new imagick(); $im->readimageblob($pdf_in); $num_pages = $im->getnumberimages(); $i = 0; for($x = 1;$x <= $num_pages; $x++) { $im = new imagick(); $im->readimageblob($pdf_in); $im->setiteratorindex($i); $im->setimageformat('png'); $img_array[$x] = $im->getimageblob(); $im->destroy(); $i++; } $im->destroy(); return $img_array; }
Производит массив с именем $ img_array со страницами входящего PDF, находящимися в ключах $ img_array в виде строк данных изображения PNG.
Там ДОЛЖЕН быть лучшим способом, почему не будет работать nextImage ()? Почему я не могу использовать setIteratorIndex без повторной инициализации / (создания новых?) Объектов imagick каждый раз? Я должен что-то упустить, но в документации есть щели, но Google, форумы ImageMagick и StackOverflow ничего не знают об этом.
ИСПЫТАНИЕ: Чрезвычайно медленный, простой PDF-файл на 17 страниц занимает почти минуту.
ОБНОВЛЕНИЕ 2: (07/11/2012) После завершения крупного проекта, в который вошел этот код, я решил вернуться к нескольким пунктам и улучшить производительность. Вот что я придумал:
$img_array = array(); $im = new imagick(); $im->readimageblob($pdf_in); $num_pages = $im->getnumberimages(); $im->destroy(); $i = 0; for($x = 1;$x <= $num_pages; $x++) { $im = new imagick(); $im->readimageblob($pdf_in); $im->setResolution(300,300); $im->setiteratorindex($i); $im->setimageformat('png'); $img_array[$x] = $im->getimageblob(); $im->destroy(); $i++; } return $img_array;
Это изменение привело к 4-страничному сложному преобразованию PDF-файла, которое длится от 21 до 25 секунд до примерно 2-3 секунд. Я понимаю, почему некоторые из изменений помогли, а не так ясно. Надеюсь, кто-то найдет это полезным.
UPDATE3: выяснилось, почему производительность так сильно выросла, перемещение «setResolution» ниже «readImageBlob» приводит к игнорированию параметра DPI, который по умолчанию равен 72. Отметив это, я переместил декларацию назад и уменьшил ее до 150 и достиг аналогичные результаты, но все же намного лучшие показатели. См. Примечания на php.net здесь .
Это чтение и уничтожение blobs все время, вероятно, замедляет нас много, на самом деле они нам не нужны, очищенный код выглядит следующим образом:
$img_array = array(); $im = new imagick(); $im->setResolution(150,150); $im->readImageBlob($pdf_in); $num_pages = $im->getNumberImages(); for($i = 0;$i < $num_pages; $i++) { $im->setIteratorIndex($i); $im->setImageFormat('jpeg'); $img_array[$i] = $im->getImageBlob(); } $im->destroy();